mirror of
https://github.com/markdavidlong/AppleSAWS.git
synced 2024-11-28 09:49:38 +00:00
Greatly improved disassembler. Added multple entry points.
This commit is contained in:
parent
2517c6d605
commit
b8ed5111fe
@ -9,12 +9,11 @@ public:
|
|||||||
BinaryFile(QByteArray data = QByteArray());
|
BinaryFile(QByteArray data = QByteArray());
|
||||||
void setData(QByteArray data);
|
void setData(QByteArray data);
|
||||||
|
|
||||||
quint16 length() { return m_length; }
|
virtual quint16 length() { return m_length; }
|
||||||
|
|
||||||
void dump();
|
void dump();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
quint16 m_length;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // BINARYFILE_H
|
#endif // BINARYFILE_H
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
#include "binaryfilemetadata.h"
|
#include "binaryfilemetadata.h"
|
||||||
|
#include <QFile>
|
||||||
|
#include <QDataStream>
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
BinaryFileMetadata::BinaryFileMetadata(GenericFile *file, quint16 defaultAddress, QObject *parent)
|
BinaryFileMetadata::BinaryFileMetadata(GenericFile *file, quint16 defaultAddress, QObject *parent)
|
||||||
: QObject(parent)
|
: QObject(parent)
|
||||||
@ -14,14 +17,32 @@ BinaryFileMetadata::BinaryFileMetadata(GenericFile *file, quint16 defaultAddress
|
|||||||
|
|
||||||
void BinaryFileMetadata::load()
|
void BinaryFileMetadata::load()
|
||||||
{
|
{
|
||||||
EntryPoint ep;
|
QFile infile(QString("%1%2").arg(m_file->filename()).arg(".bfm"));
|
||||||
ep.note = "Default Entry Point";
|
if (infile.open(QIODevice::ReadOnly))
|
||||||
ep.address = m_defaultAddress;
|
{
|
||||||
m_eps->addPoint(ep);
|
qDebug() << "Loading binary file metadata from" << QString("%1%2").arg(m_file->filename()).arg(".bfm");
|
||||||
|
QDataStream ds(&infile);
|
||||||
|
ds >> *m_eps;
|
||||||
|
ds >> *m_as;
|
||||||
|
infile.close();
|
||||||
|
}
|
||||||
|
else qDebug() << "Cannot open " << QString("%1%2").arg(m_file->filename()).arg(".bfm") << "for reading";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BinaryFileMetadata::save()
|
void BinaryFileMetadata::save()
|
||||||
{
|
{
|
||||||
|
QFile infile(QString("%1%2").arg(m_file->filename()).arg(".bfm"));
|
||||||
|
if (infile.open(QIODevice::WriteOnly))
|
||||||
|
{
|
||||||
|
qDebug() << "Saving binary file metadata to" << QString("%1%2").arg(m_file->filename()).arg(".bfm");
|
||||||
|
QDataStream ds(&infile);
|
||||||
|
ds << *m_eps;
|
||||||
|
ds << *m_as;
|
||||||
|
infile.close();
|
||||||
|
}
|
||||||
|
else qDebug() << "Cannot open " << QString("%1%2").arg(m_file->filename()).arg(".bfm") << "for writing";
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -10,7 +10,9 @@ Disassembler::Disassembler(QByteArray memimage)
|
|||||||
m_memusagemap.clearData();
|
m_memusagemap.clearData();
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<DisassembledItem> Disassembler::disassemble(quint16 from, quint16 to,bool processRecursively) {
|
QList<DisassembledItem> Disassembler::disassemble(quint16 from, quint16 to,
|
||||||
|
QList<quint16> entryPoints,
|
||||||
|
bool processRecursively) {
|
||||||
QList<DisassembledItem> retval;
|
QList<DisassembledItem> retval;
|
||||||
qDebug() << "Disassemble: From"<<uint16ToHex(from)<<"to"<<uint16ToHex(to);
|
qDebug() << "Disassemble: From"<<uint16ToHex(from)<<"to"<<uint16ToHex(to);
|
||||||
//#define OLDDISSEM
|
//#define OLDDISSEM
|
||||||
@ -32,6 +34,11 @@ QList<DisassembledItem> Disassembler::disassemble(quint16 from, quint16 to,bool
|
|||||||
|
|
||||||
bool stopping = false;
|
bool stopping = false;
|
||||||
quint16 next = from;
|
quint16 next = from;
|
||||||
|
if (entryPoints.count())
|
||||||
|
{
|
||||||
|
next = entryPoints.takeFirst();
|
||||||
|
m_jumps.append(entryPoints);
|
||||||
|
}
|
||||||
|
|
||||||
while (!stopping)
|
while (!stopping)
|
||||||
{
|
{
|
||||||
@ -100,7 +107,7 @@ QList<DisassembledItem> Disassembler::disassemble(quint16 from, quint16 to,bool
|
|||||||
if (num >= from && num <= to) // TODO: remove this to not limit disassembly to program range
|
if (num >= from && num <= to) // TODO: remove this to not limit disassembly to program range
|
||||||
{
|
{
|
||||||
qDebug() << "Calling recursively to"<<uint16ToHex(num);
|
qDebug() << "Calling recursively to"<<uint16ToHex(num);
|
||||||
retval.append(disassemble(num,to,false));
|
retval.append(disassemble(from,to,QList<quint16>() << num,false));
|
||||||
qDebug() << "Return from recursive call.";
|
qDebug() << "Return from recursive call.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,10 @@ public:
|
|||||||
P65C02
|
P65C02
|
||||||
};
|
};
|
||||||
|
|
||||||
QList<DisassembledItem> disassemble(quint16 from, quint16 to,bool processRecursively = true);
|
QList<DisassembledItem> disassemble(quint16 from,
|
||||||
|
quint16 to,
|
||||||
|
QList<quint16> entryPoints,
|
||||||
|
bool processRecursively = true);
|
||||||
|
|
||||||
MemoryUsageMap *memoryUsageMap() { return &m_memusagemap; }
|
MemoryUsageMap *memoryUsageMap() { return &m_memusagemap; }
|
||||||
|
|
||||||
|
@ -6,9 +6,11 @@ GenericFile::GenericFile(QByteArray data)
|
|||||||
setData(data);
|
setData(data);
|
||||||
}
|
}
|
||||||
m_address = 0x00;
|
m_address = 0x00;
|
||||||
|
m_length = 0x00;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenericFile::setData(QByteArray data)
|
void GenericFile::setData(QByteArray data)
|
||||||
{
|
{
|
||||||
m_data = data;
|
m_data = data;
|
||||||
|
m_length = data.size();
|
||||||
}
|
}
|
||||||
|
@ -18,10 +18,15 @@ public:
|
|||||||
virtual quint16 address() { return m_address; }
|
virtual quint16 address() { return m_address; }
|
||||||
virtual QByteArray rawData() { return m_data; }
|
virtual QByteArray rawData() { return m_data; }
|
||||||
|
|
||||||
|
virtual void setLength(quint16 length) { m_length = length; }
|
||||||
|
virtual quint16 length() { return m_length; }
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QByteArray m_data;
|
QByteArray m_data;
|
||||||
QString m_filename;
|
QString m_filename;
|
||||||
quint16 m_address;
|
quint16 m_address;
|
||||||
|
qint16 m_length;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ public:
|
|||||||
RelocatableFile(QByteArray data = QByteArray());
|
RelocatableFile(QByteArray data = QByteArray());
|
||||||
void setData(QByteArray data);
|
void setData(QByteArray data);
|
||||||
|
|
||||||
quint16 length() { return m_data.length(); }
|
virtual quint16 length() { return m_data.length(); }
|
||||||
|
|
||||||
void dump();
|
void dump();
|
||||||
|
|
||||||
|
@ -73,7 +73,12 @@ void DisassemblerViewer::setFile(BinaryFile *file) {
|
|||||||
|
|
||||||
quint16 address = file->address();
|
quint16 address = file->address();
|
||||||
|
|
||||||
QStringList formattedLines = getDisassemblyStrings(address);
|
m_mem.addFile(m_file->data(), address);
|
||||||
|
|
||||||
|
QList<quint16> addresses = m_bfm->entryPoints()->getEntryPointAddresses();
|
||||||
|
if (!addresses.count()) { addresses.append(address); }
|
||||||
|
QStringList formattedLines = getDisassemblyStrings(addresses);
|
||||||
|
|
||||||
QByteArray joinedlines = qPrintable(formattedLines.join("\n"));
|
QByteArray joinedlines = qPrintable(formattedLines.join("\n"));
|
||||||
setData(joinedlines);
|
setData(joinedlines);
|
||||||
}
|
}
|
||||||
@ -91,7 +96,11 @@ void DisassemblerViewer::setFile(RelocatableFile *file) {
|
|||||||
|
|
||||||
quint16 address = file->address() + 6 ; // Handle offset for relocatable metadata
|
quint16 address = file->address() + 6 ; // Handle offset for relocatable metadata
|
||||||
|
|
||||||
QStringList formattedLines = getDisassemblyStrings(address);
|
m_mem.addFile(m_file->data(), address);
|
||||||
|
|
||||||
|
QList<quint16> addresses = m_bfm->entryPoints()->getEntryPointAddresses();
|
||||||
|
if (!addresses.count()) { addresses.append(address); }
|
||||||
|
QStringList formattedLines = getDisassemblyStrings(addresses);
|
||||||
|
|
||||||
QByteArray joinedlines = qPrintable(formattedLines.join("\n"));
|
QByteArray joinedlines = qPrintable(formattedLines.join("\n"));
|
||||||
QStringList rd = file->decodeRelocatableDict();
|
QStringList rd = file->decodeRelocatableDict();
|
||||||
@ -102,10 +111,9 @@ void DisassemblerViewer::setFile(RelocatableFile *file) {
|
|||||||
void DisassemblerViewer::handleDisassembleRequest(QList<quint16> addresses)
|
void DisassemblerViewer::handleDisassembleRequest(QList<quint16> addresses)
|
||||||
{
|
{
|
||||||
QStringList strings;
|
QStringList strings;
|
||||||
foreach (quint16 addr, addresses)
|
|
||||||
{
|
strings += getDisassemblyStrings(addresses);
|
||||||
strings += getDisassemblyStrings(addr);
|
|
||||||
}
|
|
||||||
qSort(strings);
|
qSort(strings);
|
||||||
strings.removeDuplicates();
|
strings.removeDuplicates();
|
||||||
|
|
||||||
@ -126,23 +134,15 @@ void DisassemblerViewer::handleDisassembleRequest(QList<quint16> addresses)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QStringList DisassemblerViewer::getDisassemblyStrings(quint16 address) {
|
QStringList DisassemblerViewer::getDisassemblyStrings(QList<quint16> entryPoints) {
|
||||||
Memory mem;
|
|
||||||
mem.addFile(m_file->data(), address);
|
|
||||||
Disassembler dis(mem.values());
|
|
||||||
|
|
||||||
int length = 0;
|
Disassembler dis(m_mem.values());
|
||||||
if (dynamic_cast<BinaryFile*>(m_file))
|
|
||||||
{
|
int length = m_file->length();
|
||||||
length = (dynamic_cast<BinaryFile*>(m_file))->length();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
length = m_file->rawData().size();
|
|
||||||
}
|
|
||||||
|
|
||||||
QList<DisassembledItem> lines = dis.disassemble(m_file->address(),
|
QList<DisassembledItem> lines = dis.disassemble(m_file->address(),
|
||||||
m_file->address()+length);
|
m_file->address()+length,
|
||||||
|
entryPoints);
|
||||||
dis.setUnknownToData(m_file->address(),m_file->address()+length);
|
dis.setUnknownToData(m_file->address(),m_file->address()+length);
|
||||||
|
|
||||||
QStringList formattedLines;
|
QStringList formattedLines;
|
||||||
@ -162,14 +162,14 @@ QStringList DisassemblerViewer::getDisassemblyStrings(quint16 address) {
|
|||||||
formattedLines.append(newline);
|
formattedLines.append(newline);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int idx = address; idx < address+length; idx++)
|
for (int idx = m_file->address(); idx < m_file->address()+length; idx++)
|
||||||
{
|
{
|
||||||
if (dis.memoryUsageMap()->at(idx).testFlag(Data))
|
if (dis.memoryUsageMap()->at(idx).testFlag(Data))
|
||||||
{
|
{
|
||||||
QString newline = QString("%1: %2 %3 (%4)").arg(uint16ToHex(idx))
|
QString newline = QString("%1: %2 %3 (%4)").arg(uint16ToHex(idx))
|
||||||
.arg(uint8ToHex(mem.at(idx)))
|
.arg(uint8ToHex(m_mem.at(idx)))
|
||||||
.arg(makeDescriptorStringForVal(mem.at(idx)))
|
.arg(makeDescriptorStringForVal(m_mem.at(idx)))
|
||||||
.arg(dis.getMnemonicForOp(mem.at(idx)));
|
.arg(dis.getMnemonicForOp(m_mem.at(idx)));
|
||||||
formattedLines.append(newline);
|
formattedLines.append(newline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <QWidget>
|
#include <QWidget>
|
||||||
#include <QByteArray>
|
#include <QByteArray>
|
||||||
|
|
||||||
|
#include "memory.h"
|
||||||
#include "binaryfile.h"
|
#include "binaryfile.h"
|
||||||
#include "relocatablefile.h"
|
#include "relocatablefile.h"
|
||||||
#include "fileviewerinterface.h"
|
#include "fileviewerinterface.h"
|
||||||
@ -33,7 +34,7 @@ public:
|
|||||||
|
|
||||||
QString makeDescriptorStringForVal(quint8 val);
|
QString makeDescriptorStringForVal(quint8 val);
|
||||||
|
|
||||||
QStringList getDisassemblyStrings(quint16 address);
|
QStringList getDisassemblyStrings(QList<quint16> entryPoints);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void setFile(GenericFile *file);
|
void setFile(GenericFile *file);
|
||||||
@ -55,6 +56,7 @@ private:
|
|||||||
|
|
||||||
BinaryFileMetadata *m_bfm;
|
BinaryFileMetadata *m_bfm;
|
||||||
|
|
||||||
|
Memory m_mem;
|
||||||
|
|
||||||
bool m_isRelo;
|
bool m_isRelo;
|
||||||
};
|
};
|
||||||
|
@ -52,6 +52,7 @@ void DisassemblerMetadataDialog::handleCancelButton()
|
|||||||
|
|
||||||
void DisassemblerMetadataDialog::handleExitButton()
|
void DisassemblerMetadataDialog::handleExitButton()
|
||||||
{
|
{
|
||||||
|
m_bfm->save();
|
||||||
this->close();
|
this->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user