Debugger[Trk]: Added TCF experimental adapter.

Added adapter to work with TCF over WLAN.
Factor out common code for Symbian from TrkAdapter.
Improve message logging in TrkGdbAdapter, some cleanup.
Added new TcfTrkGdbAdapter based on TcfTrkDevice
in symbianutils based on JSON, using QTcpSocket.
To be started via special @tcf@ argument.
Rubber-stamped-by: hjk
This commit is contained in:
Friedemann Kleint
2010-06-25 15:06:30 +02:00
parent 03be40ddcd
commit beba423a16
21 changed files with 4830 additions and 315 deletions

View File

@@ -0,0 +1,215 @@
/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** GNU Lesser General Public License Usage
**
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/
#include "symbian.h"
#include <trkutils.h>
#include <utils/qtcassert.h>
#include <QtCore/QDebug>
#include <QtCore/QTextStream>
namespace Debugger {
namespace Internal {
///////////////////////////////////////////////////////////////////////////
//
// MemoryRange
//
///////////////////////////////////////////////////////////////////////////
MemoryRange::MemoryRange(uint f, uint t)
: from(f), to(t)
{
QTC_ASSERT(f <= t, qDebug() << "F: " << f << " T: " << t);
}
bool MemoryRange::intersects(const MemoryRange &other) const
{
Q_UNUSED(other);
QTC_ASSERT(false, /**/);
return false; // FIXME
}
void MemoryRange::operator-=(const MemoryRange &other)
{
if (from == 0 && to == 0)
return;
MEMORY_DEBUG(" SUB: " << *this << " - " << other);
if (other.from <= from && to <= other.to) {
from = to = 0;
return;
}
if (other.from <= from && other.to <= to) {
from = qMax(from, other.to);
return;
}
if (from <= other.from && to <= other.to) {
to = qMin(other.from, to);
return;
}
// This would split the range.
QTC_ASSERT(false, qDebug() << "Memory::operator-() not handled for: "
<< *this << " - " << other);
}
QDebug operator<<(QDebug d, const MemoryRange &range)
{
return d << QString("[%1,%2] (size %3) ")
.arg(range.from, 0, 16).arg(range.to, 0, 16).arg(range.size());
}
namespace Symbian {
static const char *registerNames[KnownRegisters] =
{
"A1", "A2", "A3", "A4",
0, 0, 0, 0,
0, 0, 0, "AP",
"IP", "SP", "LR", "PC",
"PSTrk", 0, 0, 0,
0, 0, 0, 0,
0, "PSGdb"
};
const char *registerName(int i)
{
return registerNames[i];
}
QByteArray dumpRegister(uint n, uint value)
{
QByteArray ba;
ba += ' ';
if (n < KnownRegisters && registerNames[n]) {
ba += registerNames[n];
} else {
ba += '#';
ba += QByteArray::number(n);
}
ba += '=';
ba += trk::hexxNumber(value);
return ba;
}
///////////////////////////////////////////////////////////////////////////
//
// Snapshot
//
///////////////////////////////////////////////////////////////////////////
void Snapshot::reset()
{
for (Memory::Iterator it = memory.begin(); it != memory.end(); ++it) {
if (isReadOnly(it.key())) {
MEMORY_DEBUG("KEEPING READ-ONLY RANGE" << it.key());
} else {
it = memory.erase(it);
}
}
for (int i = 0; i < RegisterCount; ++i)
registers[i] = 0;
registerValid = false;
wantedMemory = MemoryRange();
lineFromAddress = 0;
lineToAddress = 0;
}
void Snapshot::fullReset()
{
memory.clear();
reset();
}
void Snapshot::insertMemory(const MemoryRange &range, const QByteArray &ba)
{
QTC_ASSERT(range.size() == uint(ba.size()),
qDebug() << "RANGE: " << range << " BA SIZE: " << ba.size(); return);
MEMORY_DEBUG("INSERT: " << range);
// Try to combine with existing chunk.
Snapshot::Memory::iterator it = memory.begin();
Snapshot::Memory::iterator et = memory.end();
for ( ; it != et; ++it) {
if (range.from == it.key().to) {
MEMORY_DEBUG("COMBINING " << it.key() << " AND " << range);
QByteArray data = *it;
data.append(ba);
const MemoryRange res(it.key().from, range.to);
memory.remove(it.key());
MEMORY_DEBUG(" TO(1) " << res);
insertMemory(res, data);
return;
}
if (it.key().from == range.to) {
MEMORY_DEBUG("COMBINING " << range << " AND " << it.key());
QByteArray data = ba;
data.append(*it);
const MemoryRange res(range.from, it.key().to);
memory.remove(it.key());
MEMORY_DEBUG(" TO(2) " << res);
insertMemory(res, data);
return;
}
}
// Not combinable, add chunk.
memory.insert(range, ba);
}
QString Snapshot::toString() const
{
typedef QMap<MemoryRange, QByteArray>::const_iterator MemCacheConstIt;
QString rc;
QTextStream str(&rc);
str << "Register valid " << registerValid << ' ';
for (int i = 0; i < RegisterCount; i++) {
if (i)
str << ", ";
str << " R" << i << "=0x";
str.setIntegerBase(16);
str << registers[i];
str.setIntegerBase(10);
}
str << '\n';
// For next step.
if (!memory.isEmpty()) {
str.setIntegerBase(16);
str << "Memory:\n";
const MemCacheConstIt mcend = memory.constEnd();
for (MemCacheConstIt it = memory.constBegin(); it != mcend; ++it)
str << " 0x" << it.key().from << " - 0x" << it.key().to << '\n';
}
return rc;
}
} // namespace Symbian
} // namespace Internal
} // namespace Debugger