diff --git a/src/plugins/debugger/cdb/cdbassembler.cpp b/src/plugins/debugger/cdb/cdbassembler.cpp index aeb1ffec05f..93a2fcec51c 100644 --- a/src/plugins/debugger/cdb/cdbassembler.cpp +++ b/src/plugins/debugger/cdb/cdbassembler.cpp @@ -79,6 +79,35 @@ Registers getRegisters(CIDebugControl *ctl, return registers; } +bool setRegisterValueU64(CIDebugRegisters *ireg, unsigned index, quint64 value, QString *errorMessage) +{ + DEBUG_VALUE debugValueSet; + debugValueSet.Type = DEBUG_VALUE_INT64; + debugValueSet.I64 = value; + const HRESULT hr = ireg->SetValue(index, &debugValueSet); + if (FAILED(hr)) { + *errorMessage= CdbCore::msgComFailed("SetValue", hr); + false; + } + return true; +} + +bool setRegisterValueU64(CIDebugControl *ctl, + CIDebugRegisters *ireg, + const QString &name, quint64 value, + QString *errorMessage) +{ + // Look up register by name + const Registers registers = getRegisters(ctl, ireg, errorMessage); + const int regCount = registers.size(); + for (int r = 0; r < regCount; r++) + if (registers.at(r).name == name) + return setRegisterValueU64(ireg, r, value, errorMessage); + *errorMessage = QString::fromLatin1("Unable to set register '%1' to %2: No such register") + .arg(name).arg(value); + return false; +} + /* Output parser for disassembler lines: Parse a disassembler line: * \code module!class::foo: diff --git a/src/plugins/debugger/cdb/cdbassembler.h b/src/plugins/debugger/cdb/cdbassembler.h index 5aa962e71a2..2a5b5c4b67d 100644 --- a/src/plugins/debugger/cdb/cdbassembler.h +++ b/src/plugins/debugger/cdb/cdbassembler.h @@ -54,6 +54,12 @@ Registers getRegisters(CIDebugControl *ctl, QString *errorMessage, int base = 10 /* 16 for hex, etc */); +bool setRegisterValueU64(CIDebugRegisters *ireg, unsigned index, quint64 value, + QString *errorMessage); + +bool setRegisterValueU64(CIDebugControl *ctl, CIDebugRegisters *ireg, const QString &name, + quint64 value, QString *errorMessage); + bool disassemble(CdbCore::CoreEngine *engine, ULONG64 offset, unsigned long beforeLines, diff --git a/src/plugins/debugger/cdb/cdbengine.cpp b/src/plugins/debugger/cdb/cdbengine.cpp index 9d862240b1b..75d3862a116 100644 --- a/src/plugins/debugger/cdb/cdbengine.cpp +++ b/src/plugins/debugger/cdb/cdbengine.cpp @@ -1023,9 +1023,53 @@ void CdbEngine::executeRunToFunction(const QString &functionName) warning(errorMessage); } -void CdbEngine::executeJumpToLine(const QString & /* fileName */, int /*lineNumber*/) +void CdbEngine::setRegisterValue(int regnr, const QString &valueIn) { - warning(tr("Jump to line is not implemented")); + bool success = false; + QString errorMessage; + do { + const quint64 value = valueIn.toULongLong(&success, 0); + if (!success) { + errorMessage = tr("Invalid register value '%1'").arg(valueIn); + break; + } + if (!setRegisterValueU64(m_d->interfaces().debugRegisters, regnr, value, &errorMessage)) + break; + showMessage(QString::fromLatin1("Setting register %1 to 0x%2..."). + arg(regnr).arg(value, 0, 16)); + reloadRegisters(); + success =true; + } while (false); + if (!success) + warning(tr("Cannot set register %1 to '%2': %3"). + arg(regnr).arg(valueIn).arg(errorMessage)); +} + +void CdbEngine::executeJumpToLine(const QString &fileName, int lineNumber) +{ + // 'Jump' to line by manipulating the program counter register 'rip'. + bool success = false; + QString errorMessage; + do { + const quint64 address = m_d->getSourceLineAddress(fileName, lineNumber, &errorMessage); + if (address == 0) + break; + + if (!setRegisterValueU64(m_d->interfaces().debugControl, + m_d->interfaces().debugRegisters, + QLatin1String("rip"), address, &errorMessage)) + break; + showMessage(QString::fromLatin1("Jumping to %1:%2 (0x%3)..."). + arg(QDir::toNativeSeparators(fileName)).arg(lineNumber).arg(address, 0, 16)); + + StackFrame frame; + frame.file = fileName; + frame.line = lineNumber; + gotoLocation(frame, true); + success = true; + } while (false); + if (!success) + warning(tr("Cannot jump to %1:%2: %3").arg(fileName).arg(lineNumber).arg(errorMessage)); } void CdbEngine::assignValueInDebugger(const WatchData *w, const QString &expr, const QVariant &valueV) @@ -1708,7 +1752,7 @@ void CdbEngine::syncDebuggerPaths() unsigned CdbEngine::debuggerCapabilities() const { return DisassemblerCapability | RegisterCapability | ShowMemoryCapability - |WatchpointCapability + |WatchpointCapability|JumpToLineCapability |BreakOnThrowAndCatchCapability; // Sort-of: Can break on throw(). } diff --git a/src/plugins/debugger/cdb/cdbengine.h b/src/plugins/debugger/cdb/cdbengine.h index 818b327b0e4..55ab588d230 100644 --- a/src/plugins/debugger/cdb/cdbengine.h +++ b/src/plugins/debugger/cdb/cdbengine.h @@ -85,6 +85,7 @@ public: virtual void attemptBreakpointSynchronization(); + virtual void setRegisterValue(int regnr, const QString &value); virtual void fetchDisassembler(DisassemblerViewAgent *agent); virtual void fetchMemory(MemoryViewAgent *, QObject *, quint64 addr, quint64 length);