/* Handle the '"Z*" commands used by gdb to set hardware breakpoints/watchpoints. Command Format: Z*,AAAAAAAA,K Response Format: OK Where * is 1 for hardware breakpoint. 2 for write watchpoint. 3 for read watchpoint. 4 for read/write watchpoint. AAAAAAAA is the hexadecimal representation of the address on which the breakpoint should be set. K is either 2: 16-bit Thumb instruction. 3: 32-bit Thumb2 instruction. 4: 32-bit ARM insruction. value: byte size for data watchpoint. */ uint32_t HandleBreakpointWatchpointSetCommand(void) { BreakpointWatchpointArguments arguments; __try { parseBreakpointWatchpointCommandArguments(&arguments); } __catch { PrepareStringResponse(MRI_ERROR_INVALID_ARGUMENT); return 0; } switch(arguments.type) { case '1': handleHardwareBreakpointSetCommand(&arguments); break; case '2': handleWatchpointSetCommand(MRI_PLATFORM_WRITE_WATCHPOINT, &arguments); break; case '3': handleWatchpointSetCommand(MRI_PLATFORM_READ_WATCHPOINT, &arguments); break; case '4': handleWatchpointSetCommand(MRI_PLATFORM_READWRITE_WATCHPOINT, &arguments); break; default: PrepareEmptyResponseForUnknownCommand(); break; } return 0; }
/* 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 int handleGDBCommand(void) { Buffer* pBuffer = GetBuffer(); uint32_t handlerResult = 0; char commandChar; size_t i; static const struct { uint32_t (*Handler)(void); char commandChar; } commandTable[] = { {Send_T_StopResponse, '?'}, {HandleContinueCommand, 'c'}, {HandleContinueWithSignalCommand, 'C'}, {HandleFileIOCommand, 'F'}, {HandleRegisterReadCommand, 'g'}, {HandleRegisterWriteCommand, 'G'}, {HandleMemoryReadCommand, 'm'}, {HandleMemoryWriteCommand, 'M'}, {HandleQueryCommand, 'q'}, {HandleSingleStepCommand, 's'}, {HandleSingleStepWithSignalCommand, 'S'}, {HandleBinaryMemoryWriteCommand, 'X'}, {HandleBreakpointWatchpointRemoveCommand, 'z'}, {HandleBreakpointWatchpointSetCommand, 'Z'} }; getPacketFromGDB(); commandChar = Buffer_ReadChar(pBuffer); for (i = 0 ; i < ARRAY_SIZE(commandTable) ; i++) { if (commandTable[i].commandChar == commandChar) { handlerResult = commandTable[i].Handler(); if (handlerResult & HANDLER_RETURN_RETURN_IMMEDIATELY) { return handlerResult & HANDLER_RETURN_RESUME_PROGRAM; } else { break; } } } if (ARRAY_SIZE(commandTable) == i) PrepareEmptyResponseForUnknownCommand(); SendPacketToGdb(); return (handlerResult & HANDLER_RETURN_RESUME_PROGRAM); }
/* Handle the 'q' command used by gdb to communicate state to debug monitor and vice versa. Command Format: qSSS Where SSS is a variable length string indicating which query command is being sent to the stub. */ uint32_t HandleQueryCommand(void) { Buffer* pBuffer = GetBuffer(); static const char qSupportedCommand[] = "Supported"; static const char qXferCommand[] = "Xfer"; if (Buffer_MatchesString(pBuffer, qSupportedCommand, sizeof(qSupportedCommand)-1)) { return handleQuerySupportedCommand(); } else if (Buffer_MatchesString(pBuffer, qXferCommand, sizeof(qXferCommand)-1)) { return handleQueryTransferCommand(); } else { PrepareEmptyResponseForUnknownCommand(); return 0; } }