in Exdi/exdigdbsrv/GdbSrvControllerLib/GdbSrvControllerLib.cpp [137:243]
SimpleCharBuffer GdbSrvControllerImpl::ExecuteExdiGdbSrvMonitor(_In_ unsigned core, _In_ LPCWSTR pCmdToExecute)
{
assert(pCmdToExecute != nullptr);
// Check if this is an internal exdicmd function.
std::map<wstring, InternalGdbClientFunctions>::const_iterator itFunction =
m_InternalGdbFunctions.find(TargetArchitectureHelpers::WMakeLowerCase(pCmdToExecute));
if (itFunction != m_InternalGdbFunctions.end())
{
return itFunction->second();
}
HRESULT gdbServerError = S_OK;
// Are we connected to the GdbServer on this core?
if (m_pRspClient->GetRspSessionStatus(gdbServerError, core))
{
if (gdbServerError != ERROR_SUCCESS)
{
// We are not connected, so open a RSP channel and connect to it.
if (!AttachGdbSrv(GetCoreConnectionString(core), core))
{
throw _com_error(E_FAIL);
}
}
}
SimpleCharBuffer monitorResult;
if (!monitorResult.TryEnsureCapacity(C_MAX_MONITOR_CMD_BUFFER))
{
throw _com_error(E_OUTOFMEMORY);
}
if (core != C_ALLCORES && core > GetNumberOfRspConnections())
{
throw _com_error(E_INVALIDARG);
}
size_t cmdToExecMaxLength = (wcslen(pCmdToExecute) + 1) * sizeof(WCHAR);
unique_ptr<char> pCommand(new (nothrow) char[cmdToExecMaxLength]);
if (WideCharToMultiByte(CP_ACP, WC_NO_BEST_FIT_CHARS, pCmdToExecute, -1, pCommand.get(), static_cast<int>(cmdToExecMaxLength), nullptr, nullptr) == 0)
{
throw _com_error(E_INVALIDARG);
}
char * pMonitorCmd = pCommand.get();
size_t commandLength = strlen(pMonitorCmd);
std::string dataBuffer;
for (size_t idx = 0; idx < commandLength; ++idx)
{
dataBuffer.insert(dataBuffer.end(), 1, NumberToAciiHex(((pMonitorCmd[idx] >> 4) & 0xf)));
dataBuffer.insert(dataBuffer.end(), 1, NumberToAciiHex((pMonitorCmd[idx] & 0xf)));
}
std::string commandMonitor("qRcmd,");
commandMonitor += dataBuffer.c_str();
std::string reply = ExecuteCommandOnProcessor(commandMonitor.c_str(), true, 0, core);
size_t messageLength = reply.length();
// Is an empty response or an error response 'E NN'?
if (messageLength == 0 || IsReplyError(reply))
{
throw _com_error(E_FAIL);
}
messageLength = min(messageLength, C_MAX_MONITOR_CMD_BUFFER);
bool replyDone = false;
do
{
if (IsReplyOK(reply))
{
monitorResult.SetLength(monitorResult.GetLength() + messageLength);
memcpy(&monitorResult[monitorResult.GetLength() - messageLength], reply.c_str(), messageLength);
replyDone = true;
}
else
{
if (messageLength >= (monitorResult.GetCapacity() - (monitorResult.GetLength() + 1)) )
{
if (!monitorResult.TryEnsureCapacity((monitorResult.GetLength() + 1) + (4 * C_MAX_MONITOR_CMD_BUFFER)))
{
throw _com_error(E_OUTOFMEMORY);
}
}
size_t pos = (reply[0] == 'O') ? 1 : 0;
for (; pos < messageLength; pos += 2)
{
monitorResult.SetLength(monitorResult.GetLength() + 1);
unsigned char highByte = ((AciiHexToNumber(reply[pos]) << 4) & 0xf0);
monitorResult[monitorResult.GetLength() - 1] = highByte | (AciiHexToNumber(reply[pos + 1]) & 0x0f);
}
// Try to read more packets
bool IsPollingChannelMode = false;
if (m_pRspClient->ReceiveRspPacketEx(reply, core, true, IsPollingChannelMode, false))
{
messageLength = reply.length();
}
else
{
replyDone = true;
}
}
}
while (!replyDone);
return monitorResult;
}