diff --git a/src/binaryfile/binaryfilemetadata.cpp b/src/binaryfile/binaryfilemetadata.cpp index a86ab0b..5fd99d7 100644 --- a/src/binaryfile/binaryfilemetadata.cpp +++ b/src/binaryfile/binaryfilemetadata.cpp @@ -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); -// } -//} + diff --git a/src/binaryfile/binaryfilemetadata.h b/src/binaryfile/binaryfilemetadata.h index da35b9c..f12af84 100644 --- a/src/binaryfile/binaryfilemetadata.h +++ b/src/binaryfile/binaryfilemetadata.h @@ -1,51 +1,47 @@ #ifndef BINARYFILEMETADATA_H #define BINARYFILEMETADATA_H +#include "EntryPoints.h" +#include "AssemblerSymbols.h" +#include "genericfile.h" +#include "binaryfile.h" + #include #include #include +#include -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); -// 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 getEntryPointList() const { return m_entryPoints.values(); } -// QMap 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 getSymbolList() const { return m_Symbols.values(); } -// QMap getSymbolMap() const { return m_Symbols; } + void requestDisassembly() { emit doDisassemble(m_eps->getEntryPointAddresses()); } private: -// QMap m_Symbols; - QString m_filename; + EntryPoints *m_eps; + AssemblerSymbols *m_as; + + GenericFile *m_file; + + quint16 m_defaultAddress; }; #endif // BINARYFILEMETADATA_H diff --git a/src/binaryfile/disassembler.cxx b/src/binaryfile/disassembler.cxx index 81eddac..58cbfaa 100644 --- a/src/binaryfile/disassembler.cxx +++ b/src/binaryfile/disassembler.cxx @@ -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; diff --git a/src/binaryfile/disassembler.h b/src/binaryfile/disassembler.h index 94007ab..b9fd136 100644 --- a/src/binaryfile/disassembler.h +++ b/src/binaryfile/disassembler.h @@ -1,8 +1,8 @@ #ifndef DISASSEMBLER_H #define DISASSEMBLER_H -#include "util.h" #include "MemoryUsageMap.h" +#include "util.h" #include #include @@ -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 m_opcodeinfo; QByteArray m_memimage; QList m_jumps; - // QList found; MemoryUsageMap m_memusagemap; diff --git a/src/ui/viewers/disassemblerviewer.cpp b/src/ui/viewers/disassemblerviewer.cpp index a24bca3..11adf15 100644 --- a/src/ui/viewers/disassemblerviewer.cpp +++ b/src/ui/viewers/disassemblerviewer.cpp @@ -2,6 +2,7 @@ #include "ui_disassemblerviewer.h" #include "disassembler.h" #include "memory.h" +#include "util.h" #include "relocatablefile.h" #include @@ -34,6 +35,7 @@ DisassemblerViewer::~DisassemblerViewer() void DisassemblerViewer::setFile(GenericFile *file) { + if (dynamic_cast(file)) { setFile(dynamic_cast(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)), + SLOT(handleDisassembleRequest(QList))); + 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 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)), + SLOT(handleDisassembleRequest(QList))); + 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 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(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 lines = dis.disassemble(address, address+file->codeImageLength()-1); + int length = 0; + if (dynamic_cast(m_file)) + { + length = (dynamic_cast(m_file))->length(); + } + else + { + length = m_file->rawData().size(); + } + + QList 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; } diff --git a/src/ui/viewers/disassemblerviewer.h b/src/ui/viewers/disassemblerviewer.h index 1feda2c..4fa0fba 100644 --- a/src/ui/viewers/disassemblerviewer.h +++ b/src/ui/viewers/disassemblerviewer.h @@ -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 addresses); protected slots: void showMetadataDialog(); private: @@ -48,6 +53,9 @@ private: QAction *m_wordWrapAction; QAction *m_showMetadataAction; + BinaryFileMetadata *m_bfm; + + bool m_isRelo; }; diff --git a/src/ui/widgets/DisassemblerMetadataDialog.cpp b/src/ui/widgets/DisassemblerMetadataDialog.cpp index 3d8fb05..cd4b4a7 100644 --- a/src/ui/widgets/DisassemblerMetadataDialog.cpp +++ b/src/ui/widgets/DisassemblerMetadataDialog.cpp @@ -4,24 +4,17 @@ #include -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(); -} diff --git a/src/ui/widgets/DisassemblerMetadataDialog.h b/src/ui/widgets/DisassemblerMetadataDialog.h index 410d815..13a8e61 100644 --- a/src/ui/widgets/DisassemblerMetadataDialog.h +++ b/src/ui/widgets/DisassemblerMetadataDialog.h @@ -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; diff --git a/src/util/util.h b/src/util/util.h index 11186d9..d876b31 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -73,4 +73,6 @@ inline QString uint32ToHex(quint32 val) { + + #endif // UTIL_H