|
|
|
@@ -43,7 +43,7 @@ constexpr int kMaximumRegisterGroupsCount = 128;
|
|
|
|
|
constexpr int kMaximumRegisterEnumsCount = 512;
|
|
|
|
|
constexpr int kMaximumVarinfosCount = 256;
|
|
|
|
|
constexpr int kMaximumValueBitsSize = 32;
|
|
|
|
|
constexpr int kMaximumBreakpointResponseSize = 1024;
|
|
|
|
|
constexpr int kMaximumBreakpointEnumsCount = 128;
|
|
|
|
|
constexpr int kMaximumDisassembledBytesCount = 1024;
|
|
|
|
|
|
|
|
|
|
const QEvent::Type kUvscMsgEventType = static_cast<QEvent::Type>(QEvent::User + 1);
|
|
|
|
@@ -803,22 +803,28 @@ bool UvscClient::createBreakpoint(const QString &exp, quint32 &tickMark, quint64
|
|
|
|
|
if (!controlHiddenBreakpoint(exp))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
QByteArray bkparm = UvscUtils::encodeBreakPoint(BRKTYPE_EXEC, exp);
|
|
|
|
|
QByteArray bkrsp(kMaximumBreakpointResponseSize, 0);
|
|
|
|
|
qint32 bkrspLength = bkrsp.size();
|
|
|
|
|
const UVSC_STATUS st = ::UVSC_DBG_CREATE_BP(m_descriptor,
|
|
|
|
|
reinterpret_cast<BKPARM *>(bkparm.data()),
|
|
|
|
|
bkparm.size(),
|
|
|
|
|
reinterpret_cast<BKRSP *>(bkrsp.data()),
|
|
|
|
|
&bkrspLength);
|
|
|
|
|
if (st != UVSC_STATUS_SUCCESS) {
|
|
|
|
|
setError(RuntimeError);
|
|
|
|
|
// Execute command to create the BP.
|
|
|
|
|
const QString setCmd = QStringLiteral("BS %1").arg(exp);
|
|
|
|
|
QString setCmdOutput;
|
|
|
|
|
if (!executeCommand(setCmd, setCmdOutput))
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const auto bkrspPtr = reinterpret_cast<const BKRSP *>(bkrsp.constData());
|
|
|
|
|
tickMark = bkrspPtr->tickMark;
|
|
|
|
|
address = bkrspPtr->address;
|
|
|
|
|
std::vector<BKRSP> bpenums;
|
|
|
|
|
if (!enumerateBreakpoints(bpenums))
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
const auto bpenumBegin = bpenums.cbegin();
|
|
|
|
|
const auto bpenumEnd = bpenums.cend();
|
|
|
|
|
const auto bpenumIt = std::find_if(bpenumBegin, bpenumEnd, [exp](const BKRSP &bpenum) {
|
|
|
|
|
const QString bpexp = QString::fromLatin1(reinterpret_cast<const char *>(bpenum.expressionBuffer),
|
|
|
|
|
bpenum.expressionLength).trimmed();
|
|
|
|
|
return bpexp.contains(exp);
|
|
|
|
|
});
|
|
|
|
|
if (bpenumIt == bpenumEnd)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
tickMark = bpenumIt->tickMark;
|
|
|
|
|
address = bpenumIt->address;
|
|
|
|
|
|
|
|
|
|
if (!addressToFileLine(address, fileName, function, line))
|
|
|
|
|
return false;
|
|
|
|
@@ -833,11 +839,9 @@ bool UvscClient::deleteBreakpoint(quint32 tickMark)
|
|
|
|
|
BKCHG bkchg = {};
|
|
|
|
|
bkchg.type = CHG_KILLBP;
|
|
|
|
|
bkchg.tickMark = tickMark;
|
|
|
|
|
QByteArray bkrsp(kMaximumBreakpointResponseSize, 0);
|
|
|
|
|
qint32 bkrspLength = bkrsp.size();
|
|
|
|
|
const UVSC_STATUS st = ::UVSC_DBG_CHANGE_BP(m_descriptor, &bkchg, sizeof(bkchg),
|
|
|
|
|
reinterpret_cast<BKRSP *>(bkrsp.data()),
|
|
|
|
|
&bkrspLength);
|
|
|
|
|
BKRSP bkrsp = {};
|
|
|
|
|
qint32 bkrspLength = sizeof(bkrsp);
|
|
|
|
|
const UVSC_STATUS st = ::UVSC_DBG_CHANGE_BP(m_descriptor, &bkchg, sizeof(bkchg), &bkrsp, &bkrspLength);
|
|
|
|
|
if (st != UVSC_STATUS_SUCCESS) {
|
|
|
|
|
setError(RuntimeError);
|
|
|
|
|
return false;
|
|
|
|
@@ -853,11 +857,9 @@ bool UvscClient::enableBreakpoint(quint32 tickMark)
|
|
|
|
|
BKCHG bkchg = {};
|
|
|
|
|
bkchg.type = CHG_ENABLEBP;
|
|
|
|
|
bkchg.tickMark = tickMark;
|
|
|
|
|
QByteArray bkrsp(kMaximumBreakpointResponseSize, 0);
|
|
|
|
|
qint32 bkrspLength = bkrsp.size();
|
|
|
|
|
const UVSC_STATUS st = ::UVSC_DBG_CHANGE_BP(m_descriptor, &bkchg, sizeof(bkchg),
|
|
|
|
|
reinterpret_cast<BKRSP *>(bkrsp.data()),
|
|
|
|
|
&bkrspLength);
|
|
|
|
|
BKRSP bkrsp = {};
|
|
|
|
|
qint32 bkrspLength = sizeof(bkrsp);
|
|
|
|
|
const UVSC_STATUS st = ::UVSC_DBG_CHANGE_BP(m_descriptor, &bkchg, sizeof(bkchg), &bkrsp, &bkrspLength);
|
|
|
|
|
if (st != UVSC_STATUS_SUCCESS) {
|
|
|
|
|
setError(RuntimeError);
|
|
|
|
|
return false;
|
|
|
|
@@ -873,11 +875,9 @@ bool UvscClient::disableBreakpoint(quint32 tickMark)
|
|
|
|
|
BKCHG bkchg = {};
|
|
|
|
|
bkchg.type = CHG_DISABLEBP;
|
|
|
|
|
bkchg.tickMark = tickMark;
|
|
|
|
|
QByteArray bkrsp(kMaximumBreakpointResponseSize, 0);
|
|
|
|
|
qint32 bkrspLength = bkrsp.size();
|
|
|
|
|
const UVSC_STATUS st = ::UVSC_DBG_CHANGE_BP(m_descriptor, &bkchg, sizeof(bkchg),
|
|
|
|
|
reinterpret_cast<BKRSP *>(bkrsp.data()),
|
|
|
|
|
&bkrspLength);
|
|
|
|
|
BKRSP bkrsp = {};
|
|
|
|
|
qint32 bkrspLength = sizeof(bkrsp);
|
|
|
|
|
const UVSC_STATUS st = ::UVSC_DBG_CHANGE_BP(m_descriptor, &bkchg, sizeof(bkchg), &bkrsp, &bkrspLength);
|
|
|
|
|
if (st != UVSC_STATUS_SUCCESS) {
|
|
|
|
|
setError(RuntimeError);
|
|
|
|
|
return false;
|
|
|
|
@@ -903,16 +903,15 @@ bool UvscClient::controlHiddenBreakpoint(const QString &exp)
|
|
|
|
|
if (slashIndex == -1 || (slashIndex + 1) == exp.size())
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
QByteArray bkrsp(kMaximumBreakpointResponseSize, 0);
|
|
|
|
|
BKRSP bkrsp = {};
|
|
|
|
|
|
|
|
|
|
const QString hiddenExp = exp.mid(0, slashIndex);
|
|
|
|
|
QByteArray bkparm = UvscUtils::encodeBreakPoint(BRKTYPE_EXEC, hiddenExp);
|
|
|
|
|
qint32 bkrspLength = bkrsp.size();
|
|
|
|
|
qint32 bkrspLength = sizeof(bkrsp);
|
|
|
|
|
UVSC_STATUS st = ::UVSC_DBG_CREATE_BP(m_descriptor,
|
|
|
|
|
reinterpret_cast<BKPARM *>(bkparm.data()),
|
|
|
|
|
bkparm.size(),
|
|
|
|
|
reinterpret_cast<BKRSP *>(bkrsp.data()),
|
|
|
|
|
&bkrspLength);
|
|
|
|
|
&bkrsp, &bkrspLength);
|
|
|
|
|
if (st != UVSC_STATUS_SUCCESS) {
|
|
|
|
|
setError(RuntimeError);
|
|
|
|
|
return false;
|
|
|
|
@@ -920,11 +919,9 @@ bool UvscClient::controlHiddenBreakpoint(const QString &exp)
|
|
|
|
|
|
|
|
|
|
BKCHG bkchg = {};
|
|
|
|
|
bkchg.type = CHG_KILLBP;
|
|
|
|
|
bkchg.tickMark = reinterpret_cast<const BKRSP *>(bkrsp.constData())->tickMark;
|
|
|
|
|
bkrspLength = bkrsp.size();
|
|
|
|
|
st = ::UVSC_DBG_CHANGE_BP(m_descriptor, &bkchg, sizeof(bkchg),
|
|
|
|
|
reinterpret_cast<BKRSP *>(bkrsp.data()),
|
|
|
|
|
&bkrspLength);
|
|
|
|
|
bkchg.tickMark = bkrsp.tickMark;
|
|
|
|
|
bkrspLength = sizeof(bkrsp);
|
|
|
|
|
st = ::UVSC_DBG_CHANGE_BP(m_descriptor, &bkchg, sizeof(bkchg), &bkrsp, &bkrspLength);
|
|
|
|
|
if (st != UVSC_STATUS_SUCCESS) {
|
|
|
|
|
setError(RuntimeError);
|
|
|
|
|
return false;
|
|
|
|
@@ -933,6 +930,24 @@ bool UvscClient::controlHiddenBreakpoint(const QString &exp)
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool UvscClient::enumerateBreakpoints(std::vector<BKRSP> &bpenums)
|
|
|
|
|
{
|
|
|
|
|
if (!checkConnection())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
bpenums.resize(kMaximumBreakpointEnumsCount);
|
|
|
|
|
qint32 bpenumsCount = kMaximumBreakpointEnumsCount;
|
|
|
|
|
std::vector<qint32> indexes(bpenumsCount, 0);
|
|
|
|
|
const UVSC_STATUS st = ::UVSC_DBG_ENUMERATE_BP(m_descriptor, bpenums.data(),
|
|
|
|
|
indexes.data(), &bpenumsCount);
|
|
|
|
|
if (st != UVSC_STATUS_SUCCESS) {
|
|
|
|
|
setError(RuntimeError);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
bpenums.resize(bpenumsCount);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool UvscClient::calculateExpression(const QString &exp, QByteArray &)
|
|
|
|
|
{
|
|
|
|
|
if (!checkConnection())
|
|
|
|
@@ -1184,5 +1199,36 @@ bool UvscClient::addressToFileLine(quint64 address, QString &fileName,
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool UvscClient::executeCommand(const QString &cmd, QString &output)
|
|
|
|
|
{
|
|
|
|
|
if (!checkConnection())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
EXECCMD exeCmd = UvscUtils::encodeCommand(cmd);
|
|
|
|
|
UVSC_STATUS st = ::UVSC_DBG_EXEC_CMD(m_descriptor, &exeCmd, sizeof(exeCmd.command));
|
|
|
|
|
if (st != UVSC_STATUS_SUCCESS) {
|
|
|
|
|
setError(RuntimeError);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
qint32 outputLength = 0;
|
|
|
|
|
st = ::UVSC_GetCmdOutputSize(m_descriptor, &outputLength);
|
|
|
|
|
if (st != UVSC_STATUS_SUCCESS) {
|
|
|
|
|
setError(RuntimeError);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QByteArray data(outputLength, 0);
|
|
|
|
|
st = UVSC_GetCmdOutput(m_descriptor, reinterpret_cast<qint8 *>(data.data()), data.size());
|
|
|
|
|
if (st != UVSC_STATUS_SUCCESS) {
|
|
|
|
|
setError(RuntimeError);
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Note: UVSC API support only ASCII!
|
|
|
|
|
output = QString::fromLatin1(data);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace Internal
|
|
|
|
|
} // namespace Debugger
|
|
|
|
|