Commit 51f20d40 authored by hjk's avatar hjk

debugger: progress for the trk adapter

parent b2051be9
......@@ -210,6 +210,7 @@ private:
void handleAsyncOutput(const GdbMi &data);
void handleResultRecord(const GdbResultRecord &response);
void handleFileExecAndSymbols(const GdbResultRecord &response, const QVariant &);
void handleExecContinue(const GdbResultRecord &response, const QVariant &);
void handleExecRun(const GdbResultRecord &response, const QVariant &);
void handleExecJumpToLine(const GdbResultRecord &response, const QVariant &);
void handleExecRunToFunction(const GdbResultRecord &response, const QVariant &);
......
Run ./run.sh in one terminal.
Run ./gdb-symbian in a second terminal.
......@@ -112,6 +112,7 @@ private:
void handleSetBreakpoint(const TrkResult &result);
void handleClearBreakpoint(const TrkResult &result);
void handleContinue(const TrkResult &result);
void handleSignalContinue(const TrkResult &result);
void handleReadInfo(const TrkResult &result);
void handleWaitForFinished(const TrkResult &result);
void handleStep(const TrkResult &result);
......@@ -359,7 +360,21 @@ void Adapter::writeToGdb(const QByteArray &msg, const QByteArray &logNote)
void Adapter::handleGdbResponse(const QByteArray &response)
{
// http://sourceware.org/gdb/current/onlinedocs/gdb_34.html
if (response == "g") {
if (0) {}
else if (response.startsWith("C")) {
// C sig[;addr] Continue with signal sig (hex signal number)
//Reply: See section D.3 Stop Reply Packets, for the reply specifications.
bool ok = false;
uint signalNumber = response.mid(1).toInt(&ok, 16);
QByteArray ba;
appendInt(&ba, m_session.pid);
appendInt(&ba, m_session.tid);
sendTrkMessage(0x18, CB(handleSignalContinue), ba, signalNumber); // Continue
}
else if (response == "g") {
// Read general registers.
//writeToGdb("00000000", "read registers");
QByteArray ba;
......@@ -392,20 +407,68 @@ void Adapter::handleGdbResponse(const QByteArray &response)
+ QByteArray::number(m_session.currentThread));
}
else if (response == "k") {
// kill
QByteArray ba;
appendByte(&ba, 0); // Sub-command: Delete Process
appendInt(&ba, m_session.pid);
sendTrkMessage(0x41, CB(handleDeleteProcess), ba); // Delete Item
}
else if (response.startsWith("m")) {
// m addr,length
int pos = response.indexOf(',');
bool ok = false;
uint addr = response.mid(1, pos - 1).toInt(&ok, 16);
uint len = response.mid(pos + 1).toInt(&ok, 16);
//qDebug() << "ADDR: " << QByteArray::number(addr, 16) << " "
// << QByteArray::number(len, 16);
//qDebug() << "GDB ADDR: " << hexNumber(addr) << " " << hexNumber(len);
readMemory(addr, len);
}
else if (response == "pf") {
// current instruction pointer?
writeToGdb("0000", "current IP");
else if (response.startsWith("p")) {
// 0xf == current instruction pointer?
//writeToGdb("0000", "current IP");
#if 0
A1 = 0, first integer-like argument
A4 = 3, last integer-like argument
AP = 11,
IP = 12,
SP = 13, Contains address of top of stack
LR = 14, address to return to from a function call
PC = 15, Contains program counter
F0 = 16, first floating point register
F3 = 19, last floating point argument register
F7 = 23, last floating point register
FPS = 24, floating point status register
PS = 25, Contains processor status
WR0, WMMX data registers.
WR15 = WR0 + 15,
WC0, WMMX control registers.
WCSSF = WC0 + 2,
WCASF = WC0 + 3,
WC7 = WC0 + 7,
WCGR0, WMMX general purpose registers.
WCGR3 = WCGR0 + 3,
WCGR7 = WCGR0 + 7,
NUM_REGS,
// Other useful registers.
FP = 11, Frame register in ARM code, if used.
THUMB_FP = 7, Frame register in Thumb code, if used.
NUM_ARG_REGS = 4,
LAST_ARG = A4,
NUM_FP_ARG_REGS = 4,
LAST_FP_ARG = F3
#endif
bool ok = false;
uint registerNumber = response.mid(1).toInt(&ok, 16);
if (registerNumber < registerCount) {
QByteArray ba;
appendInt(&ba, m_snapshot.registers[registerNumber]);
writeToGdb(ba.toHex(), "read single known register");
} else {
writeToGdb("0000", "read single unknown register");
}
}
else if (response == "qAttached") {
......@@ -438,6 +501,12 @@ void Adapter::handleGdbResponse(const QByteArray &response)
writeToGdb(QByteArray());
}
else if (response == "qSymbol::") {
// Notify the target that GDB is prepared to serve symbol lookup requests.
writeToGdb("OK", "no further symbols needed");
//writeToGdb("qSymbol:" + QByteArray("_Z7E32Mainv").toHex(), "ask for more");
}
else if (response == "QStartNoAckMode") {
//$qSupported#37
//logMessage("Handling 'QStartNoAckMode'");
......@@ -445,6 +514,16 @@ void Adapter::handleGdbResponse(const QByteArray &response)
m_gdbAckMode = false;
}
else if (response == "vCont?") {
// actions supported by the vCont packet
writeToGdb("");
//writeToGdb("vCont;c");
}
//else if (response.startsWith("vCont")) {
// // vCont[;action[:thread-id]]...'
//}
else if (response.startsWith("?")) {
// Indicate the reason the target halted.
// The reply is the same as for step and continue.
......@@ -506,7 +585,7 @@ void Adapter::timerEvent(QTimerEvent *)
tryTrkRead();
}
unsigned char Adapter::nextTrkWriteToken()
byte Adapter::nextTrkWriteToken()
{
++m_trkWriteToken;
if (m_trkWriteToken == 0)
......@@ -881,18 +960,7 @@ void Adapter::handleAndReportReadRegisters(const TrkResult &result)
//logMessage(" RESULT: " + result.toString());
// [80 0B 00 00 00 00 00 C9 24 FF BC 00 00 00 00 00
// 60 00 00 00 00 00 00 78 67 79 70 00 00 00 00 00...]
QByteArray ba;
#if 0
char buf[30];
const char *data = result.data.data();
for (int i = 0; i != registerCount; ++i) {
uint value = extractInt(data + 4 * i + 1);
qsnprintf(buf, sizeof(buf) - 1, "%08x", value);
ba.append(buf);
}
#else
ba = result.data.toHex();
#endif
QByteArray ba = result.data.toHex();
writeToGdb(ba, "register contents");
}
......@@ -903,7 +971,7 @@ void Adapter::handleReadMemory(const TrkResult &result)
uint blockaddr = result.cookie.toInt();
//qDebug() << "READING " << ba.size() << " BYTES: "
// << quoteUnprintableLatin1(ba)
// << "ADDR: " << QByteArray::number(blockaddr, 16)
// << "ADDR: " << hexNumber(blockaddr)
// << "COOKIE: " << result.cookie;
m_snapshot.memory[blockaddr] = ba;
}
......@@ -924,7 +992,7 @@ void Adapter::reportReadMemory(const TrkResult &result)
ba = ba.mid(addr % memoryChunkSize, len);
// qDebug() << "REPORTING MEMORY " << ba.size()
// << " ADDR: " << QByteArray::number(blockaddr, 16) << " LEN: " << len
// << " ADDR: " << hexNumber(blockaddr) << " LEN: " << len
// << " BYTES: " << quoteUnprintableLatin1(ba);
writeToGdb(ba.toHex(), "memory contents");
......@@ -994,34 +1062,28 @@ void Adapter::handleClearBreakpoint(const TrkResult &result)
logMessage("CLEAR BREAKPOINT ");
}
void Adapter::handleSignalContinue(const TrkResult &result)
{
int signalNumber = result.cookie.toInt();
logMessage(" HANDLE SIGNAL CONTINUE: " + stringFromArray(result.data));
qDebug() << "NUMBER" << signalNumber;
writeToGdb("O" + QByteArray("Console output").toHex());
writeToGdb("W81"); // "Process exited with result 1
}
void Adapter::handleContinue(const TrkResult &result)
{
logMessage(" HANDLE CONTINUE: " + stringFromArray(result.data));
//if (result.result.token)
//logMessage(" ERROR: " + byte(result.result.token)
// sendTrkMessage(0x18, CB(handleContinue),
// formatInt(m_session.pid) + formatInt(m_session.tid));
//}
}
void Adapter::handleDisconnect(const TrkResult &result)
{
logMessage(" HANDLE DISCONNECT: " + stringFromArray(result.data));
//if (result.result.token)
//logMessage(" ERROR: " + byte(result.result.token)
// sendTrkMessage(0x18, CB(handleContinue),
// formatInt(m_session.pid) + formatInt(m_session.tid));
//}
}
void Adapter::handleDeleteProcess(const TrkResult &result)
{
logMessage(" HANDLE DELETE PROCESS: " + stringFromArray(result.data));
//if (result.result.token)
//logMessage(" ERROR: " + byte(result.token)
// sendTrkMessage(0x18, CB(handleContinue),
// formatInt(m_session.pid) + formatInt(m_session.tid));
//}
}
void Adapter::handleStep(const TrkResult &result)
......
......@@ -8,12 +8,12 @@ killall adapter trkserver > /dev/null 2>&1
trkservername="TRKSERVER-4";
gdbserverip=127.0.0.1
gdbserverport=2226
replaysource=dump.txt
memorydump=TrkDump-78-6a-40-00.bin
fuser -n tcp -k ${gdbserverport}
rm /tmp/${trkservername}
./trkserver ${trkservername} ${replaysource} &
./trkserver ${trkservername} ${memorydump} &
trkserverpid=$!
sleep 1
......@@ -22,19 +22,13 @@ sleep 1
adapterpid=$!
echo "
# This is generated. Changes will be lost.
set remote noack-packet on
set endian big
target remote ${gdbserverip}:${gdbserverport}
file filebrowseapp.sym
quit
" > gdb.txt
./arm-gdb -x gdb.txt
#sleep 4
kill -s USR1 ${adapterpid}
kill -s USR1 ${trkserverpid}
echo
" > .gdbinit
#kill -s USR1 ${adapterpid}
#kill -s USR1 ${trkserverpid}
#killall arm-gdb
......@@ -72,7 +72,7 @@ Inferior::Inferior()
{
pid = 0x000008F5;
tid = 0x000008F6;
codeseg = 0x78674000;
codeseg = 0x786A4000;
dataseg = 0x00400000;
}
......@@ -85,7 +85,7 @@ public:
~TrkServer();
void setServerName(const QString &name) { m_serverName = name; }
void setReplaySource(const QString &source) { m_replaySource = source; }
void setMemoryDumpName(const QString &source) { m_memoryDumpName = source; }
void startServer();
private slots:
......@@ -97,22 +97,25 @@ private slots:
private:
void logMessage(const QString &msg);
byte nextNotificationToken();
QString m_serverName;
QString m_replaySource;
QString m_memoryDumpName;
QByteArray m_adapterReadBuffer;
QList<QByteArray> m_replayData;
QByteArray m_memoryData;
QLocalServer m_server;
int m_lastSent;
QLocalSocket *m_adapterConnection;
Inferior m_inferior;
byte m_notificationToken;
};
TrkServer::TrkServer()
{
m_adapterConnection = 0;
m_notificationToken = 0;
}
TrkServer::~TrkServer()
......@@ -123,13 +126,13 @@ TrkServer::~TrkServer()
void TrkServer::startServer()
{
QFile file(m_replaySource);
QFile file(m_memoryDumpName);
file.open(QIODevice::ReadOnly);
m_replayData = file.readAll().split('\n');
m_memoryData = file.readAll();
file.close();
logMessage(QString("Read %1 lines of data from %2")
.arg(m_replayData.size()).arg(m_replaySource));
logMessage(QString("Read %1 bytes of data from %2")
.arg(m_memoryData.size()).arg(m_memoryDumpName));
m_lastSent = 0;
if (!m_server.listen(m_serverName)) {
......@@ -149,26 +152,11 @@ void TrkServer::logMessage(const QString &msg)
void TrkServer::handleConnection()
{
//QByteArray block;
//QByteArray msg = m_replayData[m_lastSent ++];
//QDataStream out(&block, QIODevice::WriteOnly);
//out.setVersion(QDataStream::Qt_4_0);
//out << (quint16)0;
//out << m_replayData;
//out.device()->seek(0);
//out << (quint16)(block.size() - sizeof(quint16));
m_adapterConnection = m_server.nextPendingConnection();
connect(m_adapterConnection, SIGNAL(disconnected()),
m_adapterConnection, SLOT(deleteLater()));
connect(m_adapterConnection, SIGNAL(readyRead()),
this, SLOT(readFromAdapter()));
//m_adapterConnection->write(block);
//m_adapterConnection->flush();
//m_adapterConnection->disconnectFromHost();
}
void TrkServer::readFromAdapter()
......@@ -198,6 +186,7 @@ void TrkServer::handleAdapterMessage(const TrkResult &result)
data.append(char(0x00)); // No error
switch (result.code) {
case 0x00: { // Ping
m_notificationToken = 0;
writeToAdapter(0x80, 0x00, data);
break;
}
......@@ -211,25 +200,58 @@ void TrkServer::handleAdapterMessage(const TrkResult &result)
Q_UNUSED(option);
ushort len = extractShort(p + 1);
uint addr = extractInt(p + 3);
qDebug() << "ADDR: " << QByteArray::number(addr, 16) << " "
<< QByteArray::number(len, 16);
//qDebug() << "MESSAGE: " << result.data.toHex();
qDebug() << "ADDR: " << hexNumber(addr) << " " << hexNumber(len);
if (addr < m_inferior.codeseg
|| addr + len >= m_inferior.codeseg + m_memoryData.size()) {
qDebug() << "ADDRESS OUTSIDE CODESEG: " << hexNumber(addr)
<< hexNumber(m_inferior.codeseg);
for (int i = 0; i != len / 4; ++i)
appendInt(&data, 0xDEADBEEF);
}
for (int i = 0; i != len; ++i)
appendByte(&data, i);
appendByte(&data, m_memoryData[addr - m_inferior.codeseg + i]);
writeToAdapter(0x80, result.token, data);
break;
}
case 0x12: { // Read Registers
appendInt(&data, 0x00000000, BigEndian);
appendInt(&data, 0xC924FFBC, BigEndian);
appendByte(&data, 0x00);
appendByte(&data, 0x00);
appendByte(&data, 0x00);
appendInt(&data, 0xC92D7FBC, BigEndian);
appendInt(&data, 0x00000000, BigEndian);
appendInt(&data, 0x00600000, BigEndian);
appendInt(&data, 0x78677970, BigEndian);
for (int i = 5; i < registerCount - 1; ++i)
appendInt(&data, i + (i << 16), BigEndian);
appendInt(&data, 0x78676B00, BigEndian);
appendInt(&data, 0x00000000, BigEndian);
appendInt(&data, 0x786A7970, BigEndian);
appendInt(&data, 0x00000000, BigEndian);
appendInt(&data, 0x00000000, BigEndian);
appendInt(&data, 0x00000012, BigEndian);
appendInt(&data, 0x00000040, BigEndian);
appendInt(&data, 0xC82AF210, BigEndian);
appendInt(&data, 0x00000000, BigEndian);
appendInt(&data, 0xC8000548, BigEndian);
appendInt(&data, 0x00403ED0, BigEndian);
appendInt(&data, 0x786A6BD8, BigEndian);
appendInt(&data, 0x786A4CC8, BigEndian);
appendInt(&data, 0x68000010, BigEndian);
writeToAdapter(0x80, result.token, data);
break;
}
case 0x18: { // Continue
writeToAdapter(0x80, result.token, data); // ACK Package
if (0) { // Fake "Stop"
QByteArray note;
appendInt(&note, 0); // FIXME: use proper address
appendInt(&note, m_inferior.pid);
appendInt(&note, m_inferior.tid);
appendByte(&note, 0x00);
appendByte(&note, 0x00);
writeToAdapter(0x90, nextNotificationToken(), note);
}
break;
}
case 0x40: { // Create Item
appendInt(&data, m_inferior.pid, BigEndian);
appendInt(&data, m_inferior.tid, BigEndian);
......@@ -238,6 +260,20 @@ void TrkServer::handleAdapterMessage(const TrkResult &result)
writeToAdapter(0x80, result.token, data);
break;
}
case 0x41: { // Delete Item
writeToAdapter(0x80, result.token, data);
// A Process?
// Command: 0xA1 Notify Deleted
//[A1 02 00 00 00 00 00 00 00 00 01 B5]
QByteArray note; // FIXME
appendByte(&note, 0);
appendByte(&note, 0);
appendInt(&note, 0);
appendInt(&note, m_inferior.pid);
writeToAdapter(0xA1, nextNotificationToken(), note);
break;
}
default:
data[0] = 0x10; // Command not supported
writeToAdapter(0xff, result.token, data);
......@@ -246,6 +282,14 @@ void TrkServer::handleAdapterMessage(const TrkResult &result)
}
byte TrkServer::nextNotificationToken()
{
++m_notificationToken;
if (m_notificationToken == 0)
++m_notificationToken;
return m_notificationToken;
}
int main(int argc, char *argv[])
{
if (argc < 3) {
......@@ -262,7 +306,7 @@ int main(int argc, char *argv[])
TrkServer server;
server.setServerName(argv[1]);
server.setReplaySource(argv[2]);
server.setMemoryDumpName(argv[2]);
server.startServer();
return app.exec();
......
......@@ -35,6 +35,11 @@
namespace trk {
QByteArray hexNumber(uint n)
{
return QByteArray::number(n, 16);
}
QString TrkResult::toString() const
{
QString res = stringFromByte(code) + "[" + stringFromByte(token);
......@@ -236,15 +241,15 @@ void appendInt(QByteArray *ba, uint i, Endianness endian)
int b1 = i % 256; i -= b1; i /= 256;
int b0 = i % 256; i -= b0; i /= 256;
if (endian == BigEndian) {
ba->append(b3);
ba->append(b2);
ba->append(b1);
ba->append(b0);
} else {
ba->append(b0);
ba->append(b1);
ba->append(b2);
ba->append(b3);
} else {
ba->append(b3);
ba->append(b2);
ba->append(b1);
ba->append(b0);
}
}
......
......@@ -72,7 +72,7 @@ enum CodeMode
enum TargetConstants
{
registerCount = 16,
registerCount = 17,
memoryChunkSize = 256
};
......@@ -147,6 +147,7 @@ struct TrkResult
QByteArray frameMessage(byte command, byte token, const QByteArray &data);
TrkResult extractResult(QByteArray *buffer);
QByteArray errorMessage(byte code);
QByteArray hexNumber(uint n);
} // namespace trk
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment