Disassembler work

This commit is contained in:
Mark Long 2016-10-26 16:44:22 -05:00
parent 18ca84b42d
commit 2517c6d605
9 changed files with 187 additions and 162 deletions

View File

@ -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);
// }
//}

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
};

View File

@ -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();
}

View File

@ -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;

View File

@ -73,4 +73,6 @@ inline QString uint32ToHex(quint32 val) {
#endif // UTIL_H