mirror of
https://github.com/markdavidlong/AppleSAWS.git
synced 2024-12-12 09:29:06 +00:00
Disassembler work
This commit is contained in:
parent
18ca84b42d
commit
2517c6d605
@ -1,84 +1,29 @@
|
||||
#include "binaryfilemetadata.h"
|
||||
|
||||
BinaryFileMetadata::BinaryFileMetadata(QString filename)
|
||||
BinaryFileMetadata::BinaryFileMetadata(GenericFile *file, quint16 defaultAddress, QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
m_filename = filename;
|
||||
m_file = file;
|
||||
m_defaultAddress = defaultAddress;
|
||||
|
||||
m_eps = new EntryPoints(this);
|
||||
m_as = new AssemblerSymbols(this);
|
||||
|
||||
load();
|
||||
}
|
||||
|
||||
//void BinaryFileMetadata::setEntryPoint(quint16 address, QString note)
|
||||
//{
|
||||
// EntryPoint ep;
|
||||
// ep.address = address;
|
||||
// ep.note = note;
|
||||
// setEntryPoint(ep);
|
||||
//}
|
||||
|
||||
//void BinaryFileMetadata::setEntryPoint(EntryPoint ep)
|
||||
//{
|
||||
// m_entryPoints.insert(ep.address,ep);
|
||||
//}
|
||||
|
||||
|
||||
//bool BinaryFileMetadata::hasEntryPointAtAddress(quint16 address)
|
||||
//{
|
||||
// return m_entryPoints.contains(address);
|
||||
//}
|
||||
|
||||
//void BinaryFileMetadata::removeEntryPoint(quint16 address)
|
||||
//{
|
||||
// if (hasEntryPointAtAddress(address))
|
||||
// {
|
||||
// m_entryPoints.remove(address);
|
||||
// }
|
||||
//}
|
||||
|
||||
bool BinaryFileMetadata::load()
|
||||
void BinaryFileMetadata::load()
|
||||
{
|
||||
// setSymbol(0x0000,"Test Symbol 1");
|
||||
// setSymbol(0x0006,"Test Symbol 2");
|
||||
// setEntryPoint(0x0010,"Test Entry Point 1");
|
||||
// setEntryPoint(0x0020,"Test Entry Point 2");
|
||||
return true;
|
||||
EntryPoint ep;
|
||||
ep.note = "Default Entry Point";
|
||||
ep.address = m_defaultAddress;
|
||||
m_eps->addPoint(ep);
|
||||
}
|
||||
|
||||
bool BinaryFileMetadata::save()
|
||||
void BinaryFileMetadata::save()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
//void BinaryFileMetadata::setSymbol(quint16 address, QString name)
|
||||
//{
|
||||
// AssemSymbol Symbol;
|
||||
// Symbol.address = address;
|
||||
// Symbol.name = name;
|
||||
// setSymbol(Symbol);
|
||||
//}
|
||||
|
||||
//void BinaryFileMetadata::setSymbol(AssemSymbol Symbol)
|
||||
//{
|
||||
// m_Symbols.insert(Symbol.address, Symbol);
|
||||
//}
|
||||
|
||||
//AssemSymbol BinaryFileMetadata::getSymbolAtAddress(quint16 address)
|
||||
//{
|
||||
// if (hasSymbolAtAddress(address))
|
||||
// {
|
||||
// return m_Symbols[address];
|
||||
// }
|
||||
// return AssemSymbol();
|
||||
//}
|
||||
|
||||
//void BinaryFileMetadata::removeSymbol(AssemSymbol Symbol)
|
||||
//{
|
||||
// removeSymbol(Symbol.address);
|
||||
//}
|
||||
|
||||
//void BinaryFileMetadata::removeSymbol(quint16 address)
|
||||
//{
|
||||
// if (hasSymbolAtAddress(address))
|
||||
// {
|
||||
// m_Symbols.remove(address);
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
@ -1,51 +1,47 @@
|
||||
#ifndef BINARYFILEMETADATA_H
|
||||
#define BINARYFILEMETADATA_H
|
||||
|
||||
#include "EntryPoints.h"
|
||||
#include "AssemblerSymbols.h"
|
||||
#include "genericfile.h"
|
||||
#include "binaryfile.h"
|
||||
|
||||
#include <Qt>
|
||||
#include <QList>
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
|
||||
|
||||
|
||||
|
||||
class BinaryFileMetadata
|
||||
class BinaryFileMetadata : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
BinaryFileMetadata(GenericFile *file, quint16 defaultAddress, QObject *parent = 0);
|
||||
|
||||
BinaryFileMetadata(QString filename);
|
||||
QString filename() const { return m_file->filename(); }
|
||||
|
||||
void setFilename(QString filename) { m_filename = filename; }
|
||||
QString filename() const { return m_filename; }
|
||||
EntryPoints *entryPoints() { return m_eps; }
|
||||
AssemblerSymbols *assemblerSymbols() { return m_as; }
|
||||
|
||||
bool load();
|
||||
bool save();
|
||||
signals:
|
||||
void doDisassemble(QList<quint16>);
|
||||
|
||||
// void setEntryPoint(quint16 address, QString note = "");
|
||||
// void setEntryPoint(EntryPoint ep);
|
||||
public slots:
|
||||
void load();
|
||||
void save();
|
||||
|
||||
// bool hasEntryPointAtAddress(EntryPoint ep);
|
||||
// bool hasEntryPointAtAddress(quint16 address);
|
||||
|
||||
// void removeEntryPoint(quint16 address);
|
||||
|
||||
// QList<EntryPoint> getEntryPointList() const { return m_entryPoints.values(); }
|
||||
// QMap<quint16,EntryPoint> getEntryPointMap() const { return m_entryPoints; }
|
||||
|
||||
// void setSymbol(quint16 address, QString name);
|
||||
// void setSymbol(AssemSymbol Symbol);
|
||||
// bool hasSymbol(AssemSymbol Symbol) const { return hasSymbolAtAddress(Symbol.address); }
|
||||
// bool hasSymbolAtAddress(quint16 address) const { return m_Symbols.contains(address); }
|
||||
// AssemSymbol getSymbolAtAddress(quint16 address);
|
||||
// void removeSymbol(AssemSymbol Symbol);
|
||||
// void removeSymbol(quint16 address);
|
||||
|
||||
// QList<AssemSymbol> getSymbolList() const { return m_Symbols.values(); }
|
||||
// QMap<quint16, AssemSymbol> getSymbolMap() const { return m_Symbols; }
|
||||
void requestDisassembly() { emit doDisassemble(m_eps->getEntryPointAddresses()); }
|
||||
|
||||
private:
|
||||
|
||||
// QMap<quint16,AssemSymbol> m_Symbols;
|
||||
QString m_filename;
|
||||
EntryPoints *m_eps;
|
||||
AssemblerSymbols *m_as;
|
||||
|
||||
GenericFile *m_file;
|
||||
|
||||
quint16 m_defaultAddress;
|
||||
};
|
||||
|
||||
#endif // BINARYFILEMETADATA_H
|
||||
|
@ -839,6 +839,17 @@ void Disassembler::makeOpcodeTable()
|
||||
|
||||
}
|
||||
|
||||
void Disassembler::setUnknownToData(quint16 from, quint16 to)
|
||||
{
|
||||
for (int idx = from; idx <= to; idx++)
|
||||
{
|
||||
if (m_memusagemap[idx].testFlag(Unknown))
|
||||
{
|
||||
m_memusagemap[idx].setFlag(Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AssyInstruction::AssyInstruction(quint8 opcode, QString mnemonic, AddressMode am) {
|
||||
m_opcode = opcode;
|
||||
m_mnemonic = mnemonic;
|
||||
|
@ -1,8 +1,8 @@
|
||||
#ifndef DISASSEMBLER_H
|
||||
#define DISASSEMBLER_H
|
||||
|
||||
#include "util.h"
|
||||
#include "MemoryUsageMap.h"
|
||||
#include "util.h"
|
||||
|
||||
#include <QByteArray>
|
||||
#include <QStringList>
|
||||
@ -149,16 +149,23 @@ public:
|
||||
|
||||
MemoryUsageMap *memoryUsageMap() { return &m_memusagemap; }
|
||||
|
||||
void setUnknownToData(quint16 from, quint16 to);
|
||||
|
||||
QString getMnemonicForOp(quint8 opcode)
|
||||
{
|
||||
return m_opcodeinfo[opcode].mnemonic();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
bool disassembleOp(quint16 address, DisassembledItem &retval, MemoryUsageMap *memuse = Q_NULLPTR);
|
||||
void makeOpcodeTable();
|
||||
|
||||
|
||||
QHash<quint8,AssyInstruction> m_opcodeinfo;
|
||||
QByteArray m_memimage;
|
||||
|
||||
QList<quint16> m_jumps;
|
||||
// QList<quint16> found;
|
||||
|
||||
MemoryUsageMap m_memusagemap;
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include "ui_disassemblerviewer.h"
|
||||
#include "disassembler.h"
|
||||
#include "memory.h"
|
||||
#include "util.h"
|
||||
#include "relocatablefile.h"
|
||||
|
||||
#include <QSettings>
|
||||
@ -34,6 +35,7 @@ DisassemblerViewer::~DisassemblerViewer()
|
||||
|
||||
void DisassemblerViewer::setFile(GenericFile *file)
|
||||
{
|
||||
|
||||
if (dynamic_cast<RelocatableFile*>(file))
|
||||
{
|
||||
setFile(dynamic_cast<RelocatableFile*>(file));
|
||||
@ -62,51 +64,86 @@ void DisassemblerViewer::setFile(BinaryFile *file) {
|
||||
m_file = file;
|
||||
m_isRelo = false;
|
||||
|
||||
m_bfm = new BinaryFileMetadata(m_file, file->address(), this);
|
||||
connect(m_bfm, SIGNAL(doDisassemble(QList<quint16>)),
|
||||
SLOT(handleDisassembleRequest(QList<quint16>)));
|
||||
|
||||
QString title = QString("Disassembler Viewer: %1").arg(m_file->filename());
|
||||
setWindowTitle(title);
|
||||
|
||||
quint16 address = file->address();
|
||||
Memory mem;
|
||||
mem.addFile(file->data(), address);
|
||||
Disassembler dis(mem.values());
|
||||
|
||||
QList<DisassembledItem> lines = dis.disassemble(file->address(), file->address()+file->length());
|
||||
|
||||
QStringList formattedLines;
|
||||
|
||||
foreach (DisassembledItem di, lines) {
|
||||
QString ds = di.rawDisassembledString();
|
||||
if (di.hasArg()) {
|
||||
QString potentialLabel = getPotentialLabel(di.arg16());
|
||||
if (!potentialLabel.isEmpty()) {
|
||||
if (ds.contains("_ARG16_")) { ds.replace("_ARG16_",potentialLabel); }
|
||||
else if (ds.contains("_ARG8_")) { ds.replace("_ARG8_",potentialLabel); }
|
||||
} else {
|
||||
ds = di.disassembledString();
|
||||
}
|
||||
}
|
||||
QString newline = QString("%1: %2 %3").arg(di.hexAddress()).arg(di.hexString()).arg(ds);
|
||||
formattedLines.append(newline);
|
||||
}
|
||||
|
||||
QStringList formattedLines = getDisassemblyStrings(address);
|
||||
QByteArray joinedlines = qPrintable(formattedLines.join("\n"));
|
||||
setData(joinedlines);
|
||||
}
|
||||
|
||||
|
||||
void DisassemblerViewer::setFile(RelocatableFile *file) {
|
||||
m_file = file;
|
||||
m_isRelo = true;
|
||||
|
||||
m_bfm = new BinaryFileMetadata(m_file, file->address() + 6, this);
|
||||
connect(m_bfm, SIGNAL(doDisassemble(QList<quint16>)),
|
||||
SLOT(handleDisassembleRequest(QList<quint16>)));
|
||||
|
||||
QString title = QString("Disassembler Viewer: %1 (Relocatable)").arg(m_file->filename());
|
||||
setWindowTitle(title);
|
||||
|
||||
quint16 address = file->address() + 6 ; // Handle offset for relocatable metadata
|
||||
|
||||
QStringList formattedLines = getDisassemblyStrings(address);
|
||||
|
||||
QByteArray joinedlines = qPrintable(formattedLines.join("\n"));
|
||||
QStringList rd = file->decodeRelocatableDict();
|
||||
QByteArray rdlines = qPrintable(rd.join("\n"));
|
||||
setData(joinedlines + "\n\n== Relocation Dictionary ==\n\n" + rdlines);
|
||||
}
|
||||
|
||||
void DisassemblerViewer::handleDisassembleRequest(QList<quint16> addresses)
|
||||
{
|
||||
QStringList strings;
|
||||
foreach (quint16 addr, addresses)
|
||||
{
|
||||
strings += getDisassemblyStrings(addr);
|
||||
}
|
||||
qSort(strings);
|
||||
strings.removeDuplicates();
|
||||
|
||||
if (m_isRelo)
|
||||
{
|
||||
QByteArray joinedlines = qPrintable(strings.join("\n"));
|
||||
QStringList rd = (dynamic_cast<RelocatableFile*>(m_file))->decodeRelocatableDict();
|
||||
QByteArray rdlines = qPrintable(rd.join("\n"));
|
||||
ui->textArea->clear();
|
||||
setData(joinedlines + "\n\n== Relocation Dictionary ==\n\n" + rdlines);
|
||||
}
|
||||
else
|
||||
{
|
||||
QByteArray joinedlines = qPrintable(strings.join("\n"));
|
||||
ui->textArea->clear();
|
||||
setData(joinedlines);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
QStringList DisassemblerViewer::getDisassemblyStrings(quint16 address) {
|
||||
Memory mem;
|
||||
mem.addFile(file->getBinaryCodeImage(), address);
|
||||
mem.addFile(m_file->data(), address);
|
||||
Disassembler dis(mem.values());
|
||||
|
||||
QList<DisassembledItem> lines = dis.disassemble(address, address+file->codeImageLength()-1);
|
||||
int length = 0;
|
||||
if (dynamic_cast<BinaryFile*>(m_file))
|
||||
{
|
||||
length = (dynamic_cast<BinaryFile*>(m_file))->length();
|
||||
}
|
||||
else
|
||||
{
|
||||
length = m_file->rawData().size();
|
||||
}
|
||||
|
||||
QList<DisassembledItem> lines = dis.disassemble(m_file->address(),
|
||||
m_file->address()+length);
|
||||
dis.setUnknownToData(m_file->address(),m_file->address()+length);
|
||||
|
||||
QStringList formattedLines;
|
||||
|
||||
@ -125,13 +162,23 @@ void DisassemblerViewer::setFile(RelocatableFile *file) {
|
||||
formattedLines.append(newline);
|
||||
}
|
||||
|
||||
QByteArray joinedlines = qPrintable(formattedLines.join("\n"));
|
||||
QStringList rd = file->decodeRelocatableDict();
|
||||
QByteArray rdlines = qPrintable(rd.join("\n"));
|
||||
setData(joinedlines + '\n' + rdlines);
|
||||
for (int idx = address; idx < address+length; idx++)
|
||||
{
|
||||
if (dis.memoryUsageMap()->at(idx).testFlag(Data))
|
||||
{
|
||||
QString newline = QString("%1: %2 %3 (%4)").arg(uint16ToHex(idx))
|
||||
.arg(uint8ToHex(mem.at(idx)))
|
||||
.arg(makeDescriptorStringForVal(mem.at(idx)))
|
||||
.arg(dis.getMnemonicForOp(mem.at(idx)));
|
||||
formattedLines.append(newline);
|
||||
}
|
||||
}
|
||||
qSort(formattedLines);
|
||||
return formattedLines;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QString DisassemblerViewer::getPotentialLabel(quint16 address) {
|
||||
QString retval = QString();
|
||||
|
||||
@ -1443,7 +1490,7 @@ bool DisassemblerViewer::optionsMenuItems(QMenu *menu)
|
||||
void DisassemblerViewer::showMetadataDialog()
|
||||
{
|
||||
if (!m_dmd) {
|
||||
m_dmd = new DisassemblerMetadataDialog(this);
|
||||
m_dmd = new DisassemblerMetadataDialog(m_bfm, this);
|
||||
m_dmd->setRelocatable(m_isRelo);
|
||||
}
|
||||
m_dmd->show();
|
||||
@ -1503,5 +1550,36 @@ void DisassemblerViewer::doExport()
|
||||
QTextStream out(&saveFile);
|
||||
out << ui->textArea->document()->toPlainText();
|
||||
saveFile.close();
|
||||
|
||||
}
|
||||
|
||||
QString DisassemblerViewer::makeDescriptorStringForVal(quint8 val)
|
||||
{
|
||||
QString retval;
|
||||
|
||||
// QString zone;
|
||||
// if (val <= 0x3f) zone = "Inverse";
|
||||
// else if (val <= 0x7f) zone = "Flash";
|
||||
// else if (val <= 0x9f) zone = "(Alt) Normal";
|
||||
// else zone = "Normal";
|
||||
|
||||
// quint8 baseascii = val;
|
||||
// if (val <= 0x1f) baseascii += 0x40;
|
||||
// else if (val <= 0x5f) baseascii += 0;
|
||||
// else if (val <= 0xbf) baseascii -= 0x40;
|
||||
// else baseascii -= 80;
|
||||
|
||||
// QString ch = QChar(baseascii);
|
||||
// if (val == 0xff) ch = "[DEL]";
|
||||
|
||||
// QString appleAscii = QString("%1 %2").arg(ch).arg(zone);
|
||||
|
||||
// if (val < 0x20)
|
||||
// {
|
||||
// QString ctrl = QString(" / (^%1)").arg(QChar(val+0x40));
|
||||
// appleAscii.append(ctrl);
|
||||
// }
|
||||
|
||||
// retval = QString("; %1 / %2").arg(val).arg(appleAscii);
|
||||
retval = QString("; %1").arg(val);
|
||||
return retval;
|
||||
}
|
||||
|
@ -31,12 +31,17 @@ public:
|
||||
bool canPrint() const;
|
||||
bool canExport() const;
|
||||
|
||||
QString makeDescriptorStringForVal(quint8 val);
|
||||
|
||||
QStringList getDisassemblyStrings(quint16 address);
|
||||
|
||||
public slots:
|
||||
void setFile(GenericFile *file);
|
||||
void toggleWordWrap(bool enabled);
|
||||
|
||||
void doPrint();
|
||||
void doExport();
|
||||
void handleDisassembleRequest(QList<quint16> addresses);
|
||||
protected slots:
|
||||
void showMetadataDialog();
|
||||
private:
|
||||
@ -48,6 +53,9 @@ private:
|
||||
QAction *m_wordWrapAction;
|
||||
QAction *m_showMetadataAction;
|
||||
|
||||
BinaryFileMetadata *m_bfm;
|
||||
|
||||
|
||||
bool m_isRelo;
|
||||
};
|
||||
|
||||
|
@ -4,24 +4,17 @@
|
||||
#include <QDebug>
|
||||
|
||||
|
||||
DisassemblerMetadataDialog::DisassemblerMetadataDialog(QWidget *parent) :
|
||||
DisassemblerMetadataDialog::DisassemblerMetadataDialog(BinaryFileMetadata *bfm, QWidget *parent) :
|
||||
QDialog(parent),
|
||||
ui(new Ui::DisassemblerMetadataDialog)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
setRelocatable(false);
|
||||
|
||||
m_bfm = new BinaryFileMetadata("Test");
|
||||
m_bfm->load();
|
||||
m_bfm = bfm;
|
||||
|
||||
m_eps = new EntryPoints(this);
|
||||
m_as = new AssemblerSymbols(this);
|
||||
|
||||
processEntryPoints();
|
||||
processSymbols();
|
||||
|
||||
m_epmodel = new EntryPointModel(this,m_eps);
|
||||
m_asmodel = new AssemblerSymbolModel(this,m_as);
|
||||
m_epmodel = new EntryPointModel(this,m_bfm->entryPoints());
|
||||
m_asmodel = new AssemblerSymbolModel(this,m_bfm->assemblerSymbols());
|
||||
|
||||
ui->entryTable->setModel(m_epmodel);
|
||||
ui->symbolTable->setModel(m_asmodel);
|
||||
@ -64,7 +57,7 @@ void DisassemblerMetadataDialog::handleExitButton()
|
||||
|
||||
void DisassemblerMetadataDialog::handleProcessButton()
|
||||
{
|
||||
|
||||
m_bfm->requestDisassembly();
|
||||
}
|
||||
|
||||
|
||||
@ -77,7 +70,7 @@ void DisassemblerMetadataDialog::handleAddEntryPointButton()
|
||||
EntryPoint ep;
|
||||
ep.address = lid.getAddress();
|
||||
ep.note = lid.getInfo();
|
||||
m_eps->addPoint(ep);
|
||||
m_bfm->entryPoints()->addPoint(ep);
|
||||
ui->entryTable->resizeRowsToContents();
|
||||
}
|
||||
}
|
||||
@ -102,7 +95,7 @@ void DisassemblerMetadataDialog::handleAddSymbolButton()
|
||||
AssemblerSymbol as;
|
||||
as.address = lid.getAddress();
|
||||
as.name = lid.getInfo();
|
||||
m_as->addSymbol(as);
|
||||
m_bfm->assemblerSymbols()->addSymbol(as);
|
||||
ui->symbolTable->resizeRowsToContents();
|
||||
}
|
||||
}
|
||||
@ -111,13 +104,3 @@ void DisassemblerMetadataDialog::handleRemoveSymbolButton()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DisassemblerMetadataDialog::processSymbols()
|
||||
{
|
||||
m_as->doTestData();
|
||||
}
|
||||
|
||||
void DisassemblerMetadataDialog::processEntryPoints()
|
||||
{
|
||||
m_eps->doTestData();
|
||||
}
|
||||
|
@ -19,14 +19,11 @@ class DisassemblerMetadataDialog : public QDialog
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DisassemblerMetadataDialog(QWidget *parent = 0);
|
||||
explicit DisassemblerMetadataDialog(BinaryFileMetadata *bfm, QWidget *parent = 0);
|
||||
~DisassemblerMetadataDialog();
|
||||
|
||||
void setRelocatable(bool relocatable);
|
||||
|
||||
void processSymbols();
|
||||
void processEntryPoints();
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent *);
|
||||
|
||||
@ -47,10 +44,8 @@ private:
|
||||
|
||||
BinaryFileMetadata *m_bfm;
|
||||
|
||||
EntryPoints *m_eps;
|
||||
EntryPointModel *m_epmodel;
|
||||
|
||||
AssemblerSymbols *m_as;
|
||||
AssemblerSymbolModel *m_asmodel;
|
||||
|
||||
bool m_isRelocatable;
|
||||
|
@ -73,4 +73,6 @@ inline QString uint32ToHex(quint32 val) {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // UTIL_H
|
||||
|
Loading…
Reference in New Issue
Block a user