forked from qt-creator/qt-creator
debugger: re-work DisassemblerLine structure
This commit is contained in:
@@ -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,18 +89,81 @@ bool DisassemblerLines::coversAddress(quint64 address) const
|
||||
return m_rowCache.value(address) != 0;
|
||||
}
|
||||
|
||||
void DisassemblerLines::appendComment(const QString &comment)
|
||||
{
|
||||
DisassemblerLine dl;
|
||||
dl.data = comment;
|
||||
m_data.append(dl);
|
||||
}
|
||||
|
||||
void DisassemblerLines::appendLine(const DisassemblerLine &dl)
|
||||
{
|
||||
m_data.append(dl);
|
||||
m_rowCache[dl.address] = m_data.size();
|
||||
}
|
||||
|
||||
void DisassemblerLines::appendUnparsed(const QString &unparsed)
|
||||
{
|
||||
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
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user