forked from qt-creator/qt-creator
Trk: Add unbuffered memory read
This commit is contained in:
@@ -81,12 +81,14 @@ static inline void dumpRegister(int n, uint value, QByteArray &a)
|
||||
}
|
||||
|
||||
struct AdapterOptions {
|
||||
AdapterOptions() : verbose(1),serialFrame(true),registerEndianness(LittleEndian),useSocket(false) {}
|
||||
AdapterOptions() : verbose(1),serialFrame(true),registerEndianness(LittleEndian),
|
||||
useSocket(false), bufferedMemoryRead(true) {}
|
||||
|
||||
int verbose;
|
||||
bool serialFrame;
|
||||
Endianness registerEndianness;
|
||||
bool useSocket;
|
||||
bool bufferedMemoryRead;
|
||||
QString gdbServer;
|
||||
QString trkServer;
|
||||
};
|
||||
@@ -106,6 +108,7 @@ public:
|
||||
void setSerialFrame(bool b) { m_serialFrame = b; }
|
||||
void setRegisterEndianness(Endianness r) { m_registerEndianness = r; }
|
||||
void setUseSocket(bool s) { m_useSocket = s; }
|
||||
void setBufferedMemoryRead(bool b) { qDebug() << "Buffered=" << b; m_bufferedMemoryRead = b; }
|
||||
bool startServer();
|
||||
|
||||
private slots:
|
||||
@@ -146,8 +149,9 @@ private:
|
||||
void handleAndReportReadRegisters(const TrkResult &result);
|
||||
QByteArray memoryReadLogMessage(uint addr, uint len, const QByteArray &ba) const;
|
||||
void handleAndReportSetBreakpoint(const TrkResult &result);
|
||||
void handleReadMemory(const TrkResult &result);
|
||||
void reportReadMemory(const TrkResult &result);
|
||||
void handleReadMemoryBuffered(const TrkResult &result);
|
||||
void handleReadMemoryUnbuffered(const TrkResult &result);
|
||||
void reportReadMemoryBuffered(const TrkResult &result);
|
||||
void reportToGdb(const TrkResult &result);
|
||||
|
||||
void clearTrkBreakpoint(const Breakpoint &bp);
|
||||
@@ -192,6 +196,7 @@ private:
|
||||
bool m_useSocket;
|
||||
bool m_serialFrame;
|
||||
bool m_startInferiorTriggered;
|
||||
bool m_bufferedMemoryRead;
|
||||
};
|
||||
|
||||
Adapter::Adapter() :
|
||||
@@ -202,7 +207,8 @@ Adapter::Adapter() :
|
||||
m_registerEndianness(LittleEndian),
|
||||
m_useSocket(false),
|
||||
m_serialFrame(true),
|
||||
m_startInferiorTriggered(false)
|
||||
m_startInferiorTriggered(false),
|
||||
m_bufferedMemoryRead(true)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -1073,20 +1079,21 @@ void Adapter::handleAndReportReadRegisters(const TrkResult &result)
|
||||
sendGdbMessage(ba, logMsg);
|
||||
}
|
||||
|
||||
static inline QString msgMemoryReadError(int code, uint addr)
|
||||
static inline QString msgMemoryReadError(int code, uint addr, uint len = 0)
|
||||
{
|
||||
return QString::fromLatin1("Memory read error %1 at: 0x%2").arg(code).arg(addr, 0 ,16);
|
||||
const QString lenS = len ? QString::number(len) : QLatin1String("<unknown>");
|
||||
return QString::fromLatin1("Memory read error %1 at: 0x%2 %3").arg(code).arg(addr, 0 ,16).arg(lenS);
|
||||
}
|
||||
|
||||
void Adapter::handleReadMemory(const TrkResult &result)
|
||||
void Adapter::handleReadMemoryBuffered(const TrkResult &result)
|
||||
{
|
||||
const uint blockaddr = result.cookie.toInt();
|
||||
const uint blockaddr = result.cookie.toUInt();
|
||||
if (const int errorCode = result.errorCode()) {
|
||||
logMessage(msgMemoryReadError(errorCode, blockaddr));
|
||||
} else {
|
||||
const QByteArray ba = result.data.mid(1);
|
||||
m_snapshot.memory.insert(blockaddr , ba);
|
||||
return;
|
||||
}
|
||||
const QByteArray ba = result.data.mid(1);
|
||||
m_snapshot.memory.insert(blockaddr , ba);
|
||||
}
|
||||
|
||||
// Format log message for memory access with some smartness about registers
|
||||
@@ -1120,9 +1127,9 @@ QByteArray Adapter::memoryReadLogMessage(uint addr, uint len, const QByteArray &
|
||||
return logMsg;
|
||||
}
|
||||
|
||||
void Adapter::reportReadMemory(const TrkResult &result)
|
||||
void Adapter::reportReadMemoryBuffered(const TrkResult &result)
|
||||
{
|
||||
const qulonglong cookie = result.cookie.toLongLong();
|
||||
const qulonglong cookie = result.cookie.toULongLong();
|
||||
const uint addr = cookie >> 32;
|
||||
const uint len = uint(cookie);
|
||||
|
||||
@@ -1141,14 +1148,27 @@ void Adapter::reportReadMemory(const TrkResult &result)
|
||||
ba.remove(0, previousChunkOverlap);
|
||||
if (ba.size() > int(len))
|
||||
ba.truncate(len);
|
||||
|
||||
if (ba.isEmpty()) {
|
||||
ba = "E20";
|
||||
sendGdbMessage(ba, msgMemoryReadError(32, addr).toLatin1());
|
||||
sendGdbMessage(ba, msgMemoryReadError(32, addr, len).toLatin1());
|
||||
} else {
|
||||
sendGdbMessage(ba.toHex(), memoryReadLogMessage(addr, len, ba));
|
||||
}
|
||||
}
|
||||
|
||||
void Adapter::handleReadMemoryUnbuffered(const TrkResult &result)
|
||||
{
|
||||
const uint blockaddr = result.cookie.toUInt();
|
||||
if (const int errorCode = result.errorCode()) {
|
||||
const QByteArray ba = "E20";
|
||||
sendGdbMessage(ba, msgMemoryReadError(32, blockaddr).toLatin1());
|
||||
} else {
|
||||
const QByteArray ba = result.data.mid(1);
|
||||
sendGdbMessage(ba.toHex(), memoryReadLogMessage(blockaddr, ba.size(), ba));
|
||||
}
|
||||
}
|
||||
|
||||
void Adapter::handleAndReportSetBreakpoint(const TrkResult &result)
|
||||
{
|
||||
//---TRK------------------------------------------------------
|
||||
@@ -1291,6 +1311,17 @@ void Adapter::cleanUp()
|
||||
// Error: 0x00
|
||||
}
|
||||
|
||||
static inline QByteArray memoryRequestTrkMessage(uint addr, uint len, int pid, int tid)
|
||||
{
|
||||
QByteArray ba;
|
||||
appendByte(&ba, 0x08); // Options, FIXME: why?
|
||||
appendShort(&ba, len);
|
||||
appendInt(&ba, addr);
|
||||
appendInt(&ba, pid);
|
||||
appendInt(&ba, tid);
|
||||
return ba;
|
||||
}
|
||||
|
||||
void Adapter::readMemory(uint addr, uint len)
|
||||
{
|
||||
Q_ASSERT(len < (2 << 16));
|
||||
@@ -1299,24 +1330,26 @@ void Adapter::readMemory(uint addr, uint len)
|
||||
if (m_verbose > 2)
|
||||
logMessage(QString::fromLatin1("readMemory %1 bytes from 0x%2 blocksize=%3").arg(len).arg(addr, 0, 16).arg(MemoryChunkSize));
|
||||
|
||||
uint blockaddr = (addr / MemoryChunkSize) * MemoryChunkSize;
|
||||
for (; blockaddr < addr + len; blockaddr += MemoryChunkSize) {
|
||||
if (!m_snapshot.memory.contains(blockaddr)) {
|
||||
if (m_verbose > 2)
|
||||
logMessage(QString::fromLatin1("Requesting memory from 0x%1").arg(blockaddr, 0, 16));
|
||||
// fetch it
|
||||
QByteArray ba;
|
||||
appendByte(&ba, 0x08); // Options, FIXME: why?
|
||||
appendShort(&ba, MemoryChunkSize);
|
||||
appendInt(&ba, blockaddr);
|
||||
appendInt(&ba, m_session.pid);
|
||||
appendInt(&ba, m_session.tid);
|
||||
// Read Memory
|
||||
sendTrkMessage(0x10, Callback(this, &Adapter::handleReadMemory), ba, QVariant(blockaddr), true);
|
||||
if (m_bufferedMemoryRead) {
|
||||
uint blockaddr = (addr / MemoryChunkSize) * MemoryChunkSize;
|
||||
for (; blockaddr < addr + len; blockaddr += MemoryChunkSize) {
|
||||
if (!m_snapshot.memory.contains(blockaddr)) {
|
||||
if (m_verbose)
|
||||
logMessage(QString::fromLatin1("Requesting buffered memory %1 bytes from 0x%2").arg(MemoryChunkSize).arg(blockaddr, 0, 16));
|
||||
sendTrkMessage(0x10, Callback(this, &Adapter::handleReadMemoryBuffered),
|
||||
memoryRequestTrkMessage(blockaddr, MemoryChunkSize, m_session.pid, m_session.tid),
|
||||
QVariant(blockaddr), true);
|
||||
}
|
||||
}
|
||||
const qulonglong cookie = (qulonglong(addr) << 32) + len;
|
||||
sendTrkMessage(TRK_WRITE_QUEUE_NOOP_CODE, Callback(this, &Adapter::reportReadMemoryBuffered), QByteArray(), cookie);
|
||||
} else {
|
||||
if (m_verbose)
|
||||
logMessage(QString::fromLatin1("Requesting unbuffered memory %1 bytes from 0x%2").arg(len).arg(addr, 0, 16));
|
||||
sendTrkMessage(0x10, Callback(this, &Adapter::handleReadMemoryUnbuffered),
|
||||
memoryRequestTrkMessage(addr, len, m_session.pid, m_session.tid),
|
||||
QVariant(addr), true);
|
||||
}
|
||||
qulonglong cookie = (qulonglong(addr) << 32) + len;
|
||||
sendTrkMessage(TRK_WRITE_QUEUE_NOOP_CODE, Callback(this, &Adapter::reportReadMemory), QByteArray(), cookie);
|
||||
}
|
||||
|
||||
void Adapter::startInferiorIfNeeded()
|
||||
@@ -1366,6 +1399,10 @@ static bool readAdapterArgs(const QStringList &args, AdapterOptions *o)
|
||||
o->useSocket = true;
|
||||
} else if (*it == QLatin1String("-f")) {
|
||||
o->serialFrame = false;
|
||||
} else if (*it == QLatin1String("-u")) {
|
||||
o->bufferedMemoryRead = false;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
switch (argNumber++) {
|
||||
@@ -1391,9 +1428,10 @@ int main(int argc, char *argv[])
|
||||
AdapterOptions options;
|
||||
|
||||
if (!readAdapterArgs(app.arguments(), &options)) {
|
||||
qDebug("Usage: %s [-v|-q] [-s][-l] <trk com/trkservername> <gdbserverport>\n"
|
||||
qDebug("Usage: %s [-v|-q] [-b][-s][-l][-u] <trk com/trkservername> <gdbserverport>\n"
|
||||
"Options: -v verbose\n"
|
||||
" -f Turn serial message frame off\n"
|
||||
" -u Turn buffered memory read off\n"
|
||||
" -q quiet\n"
|
||||
" -s Use socket (simulation)\n"
|
||||
" -b Set register endianness to big\n", argv[0]);
|
||||
@@ -1404,6 +1442,7 @@ int main(int argc, char *argv[])
|
||||
adapter.setTrkServerName(options.trkServer);
|
||||
adapter.setGdbServerName(options.gdbServer);
|
||||
adapter.setVerbose(options.verbose);
|
||||
adapter.setBufferedMemoryRead(options.bufferedMemoryRead);
|
||||
adapter.setRegisterEndianness(options.registerEndianness);
|
||||
adapter.setUseSocket(options.useSocket);
|
||||
adapter.setSerialFrame(options.serialFrame);
|
||||
|
@@ -17,10 +17,11 @@ my $trkservername;
|
||||
my $runTrkServer = 1;
|
||||
|
||||
my $usage=<<EOF;
|
||||
Usage: run.pl -av -aq -tv -tq -l [COM]
|
||||
Usage: run.pl -av -aq -au -tv -tq -l [COM]
|
||||
Options:
|
||||
-av Adapter verbose
|
||||
-aq Adapter quiet
|
||||
-au Adapter turn off buffered memory read
|
||||
-af Adapter turn off serial frame
|
||||
-tv TrkServer verbose
|
||||
-tq TrkServer quiet
|
||||
@@ -43,6 +44,8 @@ for (my $i = 0; $i < $argCount; $i++) {
|
||||
push(@ADAPTER_OPTIONS, '-q');
|
||||
} elsif ($a eq '-af') {
|
||||
push(@ADAPTER_OPTIONS, '-f');
|
||||
} elsif ($a eq '-au') {
|
||||
push(@ADAPTER_OPTIONS, '-u');
|
||||
} elsif ($a eq '-tv') {
|
||||
push(@TRKSERVEROPTIONS, '-v');
|
||||
} elsif ($a eq '-tq') {
|
||||
|
Reference in New Issue
Block a user