Commit 82f3e788 authored by hjk's avatar hjk

debugger: re-work DisassemblerLine structure

parent ffd5d69e
......@@ -1509,7 +1509,7 @@ void CdbEngine::handleDisassembler(const CdbBuiltinCommandPtr &command)
DisassemblerAgent *agent = qvariant_cast<DisassemblerAgent*>(command->cookie);
DisassemblerLines disassemblerLines;
foreach(const QByteArray &line, command->reply)
disassemblerLines.appendLine(DisassemblerLine(QString::fromLatin1(line)));
disassemblerLines.appendUnparsed(QString::fromLatin1(line));
agent->setContents(disassemblerLines);
}
......
......@@ -48,7 +48,7 @@
#include "breakhandler.h"
#include "breakwindow.h"
#include "consolewindow.h"
#include "disassembleragent.h"
#include "disassemblerlines.h"
#include "logwindow.h"
#include "moduleswindow.h"
#include "moduleshandler.h"
......@@ -1621,7 +1621,7 @@ void DebuggerPluginPrivate::requestContextMenu(ITextEditor *editor,
.section('\n', lineNumber - 1, lineNumber - 1);
BreakpointResponse needle;
needle.type = BreakpointByAddress;
needle.address = DisassemblerAgent::addressFromDisassemblyLine(line);
needle.address = DisassemblerLine::addressFromDisassemblyLine(line);
args.address = needle.address;
needle.lineNumber = -1;
id = breakHandler()->findSimilarBreakpoint(needle);
......@@ -1704,7 +1704,7 @@ void DebuggerPluginPrivate::toggleBreakpoint()
if (textEditor->property("DisassemblerView").toBool()) {
QString line = textEditor->contents()
.section('\n', lineNumber - 1, lineNumber - 1);
quint64 address = DisassemblerAgent::addressFromDisassemblyLine(line);
quint64 address = DisassemblerLine::addressFromDisassemblyLine(line);
toggleBreakpointByAddress(address);
} else if (lineNumber >= 0) {
toggleBreakpointByFileAndLine(textEditor->file()->fileName(), lineNumber);
......@@ -1751,7 +1751,7 @@ void DebuggerPluginPrivate::requestMark(ITextEditor *editor, int lineNumber)
if (editor->property("DisassemblerView").toBool()) {
QString line = editor->contents()
.section('\n', lineNumber - 1, lineNumber - 1);
quint64 address = DisassemblerAgent::addressFromDisassemblyLine(line);
quint64 address = DisassemblerLine::addressFromDisassemblyLine(line);
toggleBreakpointByAddress(address);
} else if (editor->file()) {
toggleBreakpointByFileAndLine(editor->file()->fileName(), lineNumber);
......
......@@ -265,6 +265,9 @@ QDataStream &operator>>(QDataStream &stream, WatchData &wd)
QDataStream &operator<<(QDataStream& stream, const DisassemblerLine &o)
{
stream << o.address;
stream << o.function;
stream << o.offset;
stream << o.lineNumber;
stream << o.data;
return stream;
}
......@@ -272,6 +275,9 @@ QDataStream &operator<<(QDataStream& stream, const DisassemblerLine &o)
QDataStream &operator>>(QDataStream& stream, DisassemblerLine &o)
{
stream >> o.address;
stream >> o.function;
stream >> o.offset;
stream >> o.lineNumber;
stream >> o.data;
return stream;
}
......
......@@ -254,13 +254,7 @@ void DisassemblerAgent::setContents(const DisassemblerLines &contents)
QString str;
for (int i = 0, n = contents.size(); i != n; ++i) {
const DisassemblerLine &dl = contents.at(i);
if (dl.address) {
str += QLatin1String("0x");
str += QString::number(dl.address, 16);
str += QLatin1String(" ");
}
str += dl.data;
str += contents.at(i).toString();
str += QLatin1Char('\n');
}
plainTextEdit->setPlainText(str);
......@@ -331,12 +325,6 @@ quint64 DisassemblerAgent::address() const
return d->location.address();
}
// Return address of an assembly line "0x0dfd bla"
quint64 DisassemblerAgent::addressFromDisassemblyLine(const QString &line)
{
return DisassemblerLine(line).address;
}
void DisassemblerAgent::setTryMixed(bool on)
{
d->tryMixed = on;
......
......@@ -72,9 +72,6 @@ public:
void cleanup();
bool isMixed() const;
// Return address of an assembly line "0x0dfd bla"
static quint64 addressFromDisassemblyLine(const QString &data);
private:
DisassemblerAgentPrivate *d;
};
......
......@@ -32,6 +32,7 @@
**************************************************************************/
#include "disassemblerlines.h"
#include "debuggerstringutils.h"
#include <QtCore/QDebug>
#include <QtCore/QRegExp>
......@@ -39,7 +40,7 @@
namespace Debugger {
namespace Internal {
DisassemblerLine::DisassemblerLine(const QString &unparsed)
void DisassemblerLine::fromString(const QString &unparsed)
{
int pos = -1;
for (int i = 0; i != unparsed.size(); ++i) {
......@@ -71,6 +72,13 @@ DisassemblerLine::DisassemblerLine(const QString &unparsed)
data = unparsed;
}
quint64 DisassemblerLine::addressFromDisassemblyLine(const QString &line)
{
DisassemblerLine l;
l.fromString(line);
return l.address;
}
int DisassemblerLines::lineForAddress(quint64 address) const
{
return m_rowCache.value(address);
......@@ -81,17 +89,80 @@ bool DisassemblerLines::coversAddress(quint64 address) const
return m_rowCache.value(address) != 0;
}
void DisassemblerLines::appendComment(const QString &comment)
void DisassemblerLines::appendLine(const DisassemblerLine &dl)
{
DisassemblerLine dl;
dl.data = comment;
m_data.append(dl);
m_rowCache[dl.address] = m_data.size();
}
void DisassemblerLines::appendLine(const DisassemblerLine &dl)
void DisassemblerLines::appendUnparsed(const QString &unparsed)
{
m_data.append(dl);
m_rowCache[dl.address] = m_data.size();
QString line = unparsed.trimmed();
if (line.isEmpty())
return;
if (line.startsWith("Current language:"))
return;
if (line.startsWith("Dump of assembler")) {
m_lastFunction.clear();
return;
}
if (line.startsWith("The current source"))
return;
if (line.startsWith("End of assembler")) {
m_lastFunction.clear();
return;
}
if (line.startsWith("=> "))
line = line.mid(3);
if (line.startsWith("0x")) {
// Address line.
int pos1 = line.indexOf('<') + 1;
int pos2 = line.indexOf('+', pos1);
int pos3 = line.indexOf('>', pos1);
if (pos1 < pos2 && pos2 < pos3) {
QString function = line.mid(pos1, pos2 - pos1);
if (function != m_lastFunction) {
DisassemblerLine dl;
dl.data = _("Function: ") + function;
m_data.append(dl);
m_lastFunction = function;
}
//line.replace(pos1, pos2 - pos1, "");
}
DisassemblerLine dl;
dl.address = line.left(pos1 - 1).toULongLong(0, 0);
dl.function = m_lastFunction;
dl.offset = line.mid(pos2, pos3 - pos2).toUInt();
dl.data = line.mid(pos3 + 3).trimmed();
m_rowCache[dl.address] = m_data.size() + 1;
m_data.append(dl);
} else {
// Comment line.
DisassemblerLine dl;
dl.data = line;
m_data.append(dl);
}
}
QString DisassemblerLine::toString() const
{
const QString someSpace = _(" ");
QString str;
if (isAssembler()) {
if (address)
str += _("0x%1 ").arg(address, 0, 16);
if (offset)
str += _("<+0x%1> ").arg(offset, 4, 10, QLatin1Char('0'));
str += _(" ");
str += data;
} else if (isCode()) {
str += someSpace;
str += data;
} else {
str += someSpace;
str += data;
}
return str;
}
} // namespace Internal
......
......@@ -41,15 +41,31 @@
namespace Debugger {
namespace Internal {
// A DisassemblerLine represents either
// - an assembler instruction (address, offset, function, data fields), or
// - a code line (lineNumber, data fields), or
// - a comment line.
class DisassemblerLine
{
//DisassemblerLine(const QString &unparsed);
public:
DisassemblerLine() : address(0) {}
DisassemblerLine(const QString &unparsed);
DisassemblerLine() : address(0), offset(0), lineNumber(0) {}
bool isAssembler() const { return address != 0; }
bool isCode() const { return lineNumber != 0; }
bool isComment() const { return lineNumber == 0 && address == 0; }
QString toString() const;
void fromString(const QString &unparsed);
// Return address of an assembly line "0x0dfd bla".
static quint64 addressFromDisassemblyLine(const QString &line);
public:
quint64 address;
QString data;
quint64 address; // (ass) Address of instruction in memory/in binary.
QString function; // (ass) Function to which current instruction belongs.
uint offset; // (ass) Offset of instruction in relation to current function.
uint lineNumber; // (src) Line number in source.
QString data; // (ass) Instruction text, (src) source text, (cmt) arbitrary.
};
class DisassemblerLines
......@@ -58,13 +74,14 @@ public:
DisassemblerLines() {}
bool coversAddress(quint64 address) const;
void appendUnparsed(const QString &line);
void appendLine(const DisassemblerLine &dl);
void appendComment(const QString &comment);
int size() const { return m_data.size(); }
const DisassemblerLine &at(int i) const { return m_data.at(i); }
int lineForAddress(quint64 address) const;
private:
QString m_lastFunction;
QVector<DisassemblerLine> m_data;
QHash<quint64, int> m_rowCache;
};
......
......@@ -4119,6 +4119,8 @@ static DisassemblerLine parseLine(const GdbMi &line)
QByteArray address = line.findChild("address").data();
dl.address = address.toULongLong();
dl.data = _(line.findChild("inst").data());
dl.function = _(line.findChild("func-name").data());
dl.offset = line.findChild("offset").data().toUInt();
return dl;
}
......@@ -4153,8 +4155,12 @@ DisassemblerLines GdbEngine::parseMiDisassembler(const GdbMi &lines)
fileLoaded = true;
}
int line = child.findChild("line").data().toInt();
if (line >= 1 && line <= fileContents.size())
result.appendComment(fileContents.at(line - 1));
if (line >= 1 && line <= fileContents.size()) {
DisassemblerLine dl;
dl.lineNumber = line;
dl.data = fileContents.at(line - 1);
result.appendLine(dl);
}
GdbMi insn = child.findChild("line_asm_insn");
foreach (const GdbMi &item, insn.children())
result.appendLine(parseLine(item));
......@@ -4172,45 +4178,8 @@ DisassemblerLines GdbEngine::parseCliDisassembler(const GdbMi &output)
// First line is something like
// "Dump of assembler code from 0xb7ff598f to 0xb7ff5a07:"
DisassemblerLines dlines;
QByteArray lastFunction;
foreach (const QByteArray &line0, output.data().split('\n')) {
QByteArray line = line0.trimmed();
if (line.startsWith("=> "))
line = line.mid(3);
if (line.isEmpty())
continue;
if (line.startsWith("Current language:"))
continue;
if (line.startsWith("Dump of assembler"))
continue;
if (line.startsWith("The current source"))
continue;
if (line.startsWith("End of assembler"))
continue;
if (line.startsWith("0x")) {
int pos1 = line.indexOf('<') + 1;
int pos2 = line.indexOf('+', pos1);
int pos3 = line.indexOf('>', pos1);
if (pos1 < pos2 && pos2 < pos3) {
QByteArray function = line.mid(pos1, pos2 - pos1);
if (function != lastFunction) {
dlines.appendComment(QString());
dlines.appendComment(_("Function: ") + _(function));
lastFunction = function;
}
line.replace(pos1, pos2 - pos1, "");
}
if (pos3 - pos2 == 1)
line.insert(pos2 + 1, "000");
if (pos3 - pos2 == 2)
line.insert(pos2 + 1, "00");
if (pos3 - pos2 == 3)
line.insert(pos2 + 1, "0");
dlines.appendLine(DisassemblerLine(_(line)));
continue;
}
dlines.appendComment(someSpace + _(line));
}
foreach (const QByteArray &line, output.data().split('\n'))
dlines.appendUnparsed(_(line));
return dlines;
}
......
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