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);
}
#include "breakhandler.h"
#include "breakwindow.h"
#include "consolewindow.h"
-#include "disassembleragent.h"
+#include "disassemblerlines.h"
#include "logwindow.h"
#include "moduleswindow.h"
#include "moduleshandler.h"
.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);
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);
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);
QDataStream &operator<<(QDataStream& stream, const DisassemblerLine &o)
{
stream << o.address;
+ stream << o.function;
+ stream << o.offset;
+ stream << o.lineNumber;
stream << o.data;
return stream;
}
QDataStream &operator>>(QDataStream& stream, DisassemblerLine &o)
{
stream >> o.address;
+ stream >> o.function;
+ stream >> o.offset;
+ stream >> o.lineNumber;
stream >> o.data;
return stream;
}
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);
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;
void cleanup();
bool isMixed() const;
- // Return address of an assembly line "0x0dfd bla"
- static quint64 addressFromDisassemblyLine(const QString &data);
-
private:
DisassemblerAgentPrivate *d;
};
**************************************************************************/
#include "disassemblerlines.h"
+#include "debuggerstringutils.h"
#include <QtCore/QDebug>
#include <QtCore/QRegExp>
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) {
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);
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
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
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;
};
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;
}
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));
// 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;
}