diff --git a/src/plugins/debugger/gdb/symbian.cpp b/src/plugins/debugger/gdb/symbian.cpp index 4cae2ce81bc..636c83da85e 100644 --- a/src/plugins/debugger/gdb/symbian.cpp +++ b/src/plugins/debugger/gdb/symbian.cpp @@ -548,7 +548,7 @@ QVector gdbStartupSequence() } // namespace Symbian // Generic gdb server helpers: Read address/length off a memory -// command like 'm845,455','X845,455' +// command like 'm845,455','X845,455:' QPair parseGdbReadMemoryRequest(const QByteArray &cmd) { QPair rc(0, 0); @@ -559,7 +559,11 @@ QPair parseGdbReadMemoryRequest(const QByteArray &cmd) rc.first = cmd.mid(1, pos - 1).toULongLong(&ok, 16); if (!ok) return rc; - rc.second = cmd.mid(pos + 1).toUInt(&ok, 16); + const int colonPos = cmd.indexOf(':'); + if (colonPos == -1) + rc.second = cmd.mid(pos + 1).toUInt(&ok, 16); + else + rc.second = cmd.mid(pos + 1, colonPos - pos - 1 ).toUInt(&ok, 16); if (!ok) rc.first = 0; return rc; diff --git a/src/plugins/debugger/gdb/trkgdbadapter.cpp b/src/plugins/debugger/gdb/trkgdbadapter.cpp index 1e32fcb26fd..05d1ba6bc40 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.cpp +++ b/src/plugins/debugger/gdb/trkgdbadapter.cpp @@ -829,6 +829,17 @@ void TrkGdbAdapter::handleGdbServerCommand(const QByteArray &cmd) sendGdbServerMessage("E20", msg.toLatin1()); } } // qPart/qXfer + + else if (cmd.startsWith("X")) { + logMessage(msgGdbPacket(QLatin1String("Write memory"))); + // X addr,length + sendGdbServerAck(); + const QPair addrLength = parseGdbReadMemoryRequest(cmd); + int pos = cmd.indexOf(':'); + m_snapshot.resetMemory(); + writeMemory(addrLength.first, cmd.mid(pos + 1, addrLength.second)); + } + else { logMessage(msgGdbPacket(QLatin1String("FIXME unknown: ") + QString::fromAscii(cmd)), LogWarning); @@ -1444,6 +1455,29 @@ void TrkGdbAdapter::readMemory(uint addr, uint len, bool buffered) tryAnswerGdbMemoryRequest(buffered); } +void TrkGdbAdapter::writeMemory(uint addr, const QByteArray &data) +{ + Q_ASSERT(data.size() < (2 << 16)); + if (m_verbose > 2) { + logMessage(_("writeMemory %1 bytes from 0x%2 blocksize=%3 data=%4") + .arg(data.size()).arg(addr, 0, 16).arg(MemoryChunkSize).arg(QString::fromLatin1(data.toHex()))); + } + + sendTrkMessage(0x11, TrkCB(handleWriteMemory), + trkWriteMemoryMessage(addr, data)); +} + +void TrkGdbAdapter::handleWriteMemory(const TrkResult &result) +{ + logMessage(" RESULT: " + result.toString() + result.cookie.toString()); + if (result.errorCode()) { + logMessage("ERROR: " + result.errorString(), LogError); + sendGdbServerMessage("E01"); + return; + } + sendGdbServerMessage("OK"); +} + void TrkGdbAdapter::interruptInferior() { sendTrkMessage(0x1a, TrkCallback(), trkInterruptMessage(), "Interrupting..."); diff --git a/src/plugins/debugger/gdb/trkgdbadapter.h b/src/plugins/debugger/gdb/trkgdbadapter.h index 1e7873815e9..2ea7e1bcfab 100644 --- a/src/plugins/debugger/gdb/trkgdbadapter.h +++ b/src/plugins/debugger/gdb/trkgdbadapter.h @@ -162,12 +162,14 @@ private: void handleStep(const TrkResult &result); void handleReadRegisters(const TrkResult &result); void handleWriteRegister(const TrkResult &result); + void handleWriteMemory(const TrkResult &result); void reportToGdb(const TrkResult &result); void gdbSetCurrentThread(const QByteArray &cmd, const char *why); //void reportReadMemoryBuffered(const TrkResult &result); //void reportReadMemoryUnbuffered(const TrkResult &result); void readMemory(uint addr, uint len, bool buffered); + void writeMemory(uint addr, const QByteArray &data); void handleDirectTrk(const TrkResult &response); void directStep(uint addr);