Core: Start improving memory search
Vicki Pfau vi@endrift.com
Sat, 14 Oct 2017 15:36:51 -0700
3 files changed,
151 insertions(+),
141 deletions(-)
M
include/mgba/core/mem-search.h
→
include/mgba/core/mem-search.h
@@ -13,9 +13,7 @@
#include <mgba-util/vector.h> enum mCoreMemorySearchType { - mCORE_MEMORY_SEARCH_32, - mCORE_MEMORY_SEARCH_16, - mCORE_MEMORY_SEARCH_8, + mCORE_MEMORY_SEARCH_INT, mCORE_MEMORY_SEARCH_STRING, mCORE_MEMORY_SEARCH_GUESS, };@@ -23,11 +21,11 @@
struct mCoreMemorySearchParams { int memoryFlags; enum mCoreMemorySearchType type; + int align; + int width; union { const char* valueStr; - uint32_t value32; - uint32_t value16; - uint32_t value8; + uint32_t valueInt; }; };@@ -35,7 +33,9 @@ struct mCoreMemorySearchResult {
uint32_t address; int segment; uint64_t guessDivisor; + uint64_t guessMultiplier; enum mCoreMemorySearchType type; + int width; }; DECLARE_VECTOR(mCoreMemorySearchResults, struct mCoreMemorySearchResult);
M
src/core/mem-search.c
→
src/core/mem-search.c
@@ -29,33 +29,41 @@ }
if ((mask & 1) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i; - res->type = mCORE_MEMORY_SEARCH_32; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 4; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 2) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 4; - res->type = mCORE_MEMORY_SEARCH_32; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 4; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 4) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 8; - res->type = mCORE_MEMORY_SEARCH_32; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 4; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 8) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 12; - res->type = mCORE_MEMORY_SEARCH_32; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 4; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } }@@ -86,65 +94,81 @@ }
if ((mask & 1) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i; - res->type = mCORE_MEMORY_SEARCH_16; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 2; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 2) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 2; - res->type = mCORE_MEMORY_SEARCH_16; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 2; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 4) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 4; - res->type = mCORE_MEMORY_SEARCH_16; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 2; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 8) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 6; - res->type = mCORE_MEMORY_SEARCH_16; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 2; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 16) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 8; - res->type = mCORE_MEMORY_SEARCH_16; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 2; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 32) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 10; - res->type = mCORE_MEMORY_SEARCH_16; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 2; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 64) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 12; - res->type = mCORE_MEMORY_SEARCH_16; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 2; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 128) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 14; - res->type = mCORE_MEMORY_SEARCH_16; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 2; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } }@@ -174,65 +198,81 @@ }
if ((mask & 1) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i; - res->type = mCORE_MEMORY_SEARCH_8; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 1; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 2) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 1; - res->type = mCORE_MEMORY_SEARCH_8; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 1; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 4) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 2; - res->type = mCORE_MEMORY_SEARCH_8; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 1; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 8) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 3; - res->type = mCORE_MEMORY_SEARCH_8; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 1; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 16) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 4; - res->type = mCORE_MEMORY_SEARCH_8; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 1; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 32) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 5; - res->type = mCORE_MEMORY_SEARCH_8; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 1; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 64) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 6; - res->type = mCORE_MEMORY_SEARCH_8; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 1; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } if ((mask & 128) && (!limit || found < limit)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i + 7; - res->type = mCORE_MEMORY_SEARCH_8; + res->type = mCORE_MEMORY_SEARCH_INT; + res->width = 1; res->segment = -1; // TODO res->guessDivisor = 1; + res->guessMultiplier = 1; ++found; } }@@ -240,18 +280,32 @@ // TODO: last 7 bytes
return found; } -static size_t _searchStr(const void* mem, size_t size, const struct mCoreMemoryBlock* block, const char* valueStr, struct mCoreMemorySearchResults* out, size_t limit) { +static size_t _searchInt(const void* mem, size_t size, const struct mCoreMemoryBlock* block, const struct mCoreMemorySearchParams* params, struct mCoreMemorySearchResults* out, size_t limit) { + if (params->align == params->width || params->align == -1) { + switch (params->width) { + case 4: + return _search32(mem, size, block, params->valueInt, out, limit); + case 2: + return _search16(mem, size, block, params->valueInt, out, limit); + case 1: + return _search8(mem, size, block, params->valueInt, out, limit); + } + } + return 0; +} + +static size_t _searchStr(const void* mem, size_t size, const struct mCoreMemoryBlock* block, const char* valueStr, int len, struct mCoreMemorySearchResults* out, size_t limit) { const char* memStr = mem; size_t found = 0; - size_t len = strlen(valueStr); uint32_t start = block->start; uint32_t end = size; // TODO: Segments size_t i; for (i = 0; (!limit || found < limit) && i < end - len; ++i) { - if (!strncmp(valueStr, &memStr[i], len)) { + if (!memcmp(valueStr, &memStr[i], len)) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsAppend(out); res->address = start + i; res->type = mCORE_MEMORY_SEARCH_STRING; + res->width = len; res->segment = -1; // TODO ++found; }@@ -342,14 +396,10 @@ }
static size_t _search(const void* mem, size_t size, const struct mCoreMemoryBlock* block, const struct mCoreMemorySearchParams* params, struct mCoreMemorySearchResults* out, size_t limit) { switch (params->type) { - case mCORE_MEMORY_SEARCH_32: - return _search32(mem, size, block, params->value32, out, limit); - case mCORE_MEMORY_SEARCH_16: - return _search16(mem, size, block, params->value16, out, limit); - case mCORE_MEMORY_SEARCH_8: - return _search8(mem, size, block, params->value8, out, limit); + case mCORE_MEMORY_SEARCH_INT: + return _searchInt(mem, size, block, params, out, limit); case mCORE_MEMORY_SEARCH_STRING: - return _searchStr(mem, size, block, params->valueStr, out, limit); + return _searchStr(mem, size, block, params->valueStr, params->width, out, limit); case mCORE_MEMORY_SEARCH_GUESS: return _searchGuess(mem, size, block, params->valueStr, out, limit); }@@ -384,26 +434,26 @@ char* end;
value = strtoull(params->valueStr, &end, 10); if (end) { - if (core->rawRead8(core, res->address, res->segment) * res->guessDivisor == value) { + if (core->rawRead8(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) { return true; } - if (!(res->address & 1) && core->rawRead16(core, res->address, res->segment) * res->guessDivisor == value) { + if (!(res->address & 1) && core->rawRead16(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) { return true; } - if (!(res->address & 3) && core->rawRead32(core, res->address, res->segment) * res->guessDivisor == value) { + if (!(res->address & 3) && core->rawRead32(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) { return true; } } value = strtoull(params->valueStr, &end, 16); if (end) { - if (core->rawRead8(core, res->address, res->segment) * res->guessDivisor == value) { + if (core->rawRead8(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) { return true; } - if (!(res->address & 1) && core->rawRead16(core, res->address, res->segment) * res->guessDivisor == value) { + if (!(res->address & 1) && core->rawRead16(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) { return true; } - if (!(res->address & 3) && core->rawRead32(core, res->address, res->segment) * res->guessDivisor == value) { + if (!(res->address & 3) && core->rawRead32(core, res->address, res->segment) * res->guessDivisor / res->guessMultiplier == value) { return true; } }@@ -415,69 +465,27 @@ size_t i;
for (i = 0; i < mCoreMemorySearchResultsSize(inout); ++i) { struct mCoreMemorySearchResult* res = mCoreMemorySearchResultsGetPointer(inout, i); switch (res->type) { - case mCORE_MEMORY_SEARCH_8: - switch (params->type) { - case mCORE_MEMORY_SEARCH_8: - if (core->rawRead8(core, res->address, res->segment) != params->value8) { + case mCORE_MEMORY_SEARCH_INT: + switch (params->width) { + case 1: + if (core->rawRead8(core, res->address, res->segment) != params->valueInt) { mCoreMemorySearchResultsShift(inout, i, 1); --i; } break; - case mCORE_MEMORY_SEARCH_16: - if (core->rawRead8(core, res->address, res->segment) != params->value16) { + case 2: + if (core->rawRead8(core, res->address, res->segment) != params->valueInt) { mCoreMemorySearchResultsShift(inout, i, 1); --i; } break; - case mCORE_MEMORY_SEARCH_32: - if (core->rawRead32(core, res->address, res->segment) != params->value32) { + case 4: + if (core->rawRead32(core, res->address, res->segment) != params->valueInt) { mCoreMemorySearchResultsShift(inout, i, 1); --i; } break; - case mCORE_MEMORY_SEARCH_GUESS: - if (!_testGuess(core, res, params)) { - mCoreMemorySearchResultsShift(inout, i, 1); - --i; - } - break; - default: - break; - } - break; - case mCORE_MEMORY_SEARCH_16: - switch (params->type) { - case mCORE_MEMORY_SEARCH_16: - if (core->rawRead16(core, res->address, res->segment) != params->value16) { - mCoreMemorySearchResultsShift(inout, i, 1); - --i; - } - break; - case mCORE_MEMORY_SEARCH_32: - if (core->rawRead32(core, res->address, res->segment) != params->value32) { - mCoreMemorySearchResultsShift(inout, i, 1); - --i; - } - break; - case mCORE_MEMORY_SEARCH_GUESS: - if (!_testGuess(core, res, params)) { - mCoreMemorySearchResultsShift(inout, i, 1); - --i; - } - break; - default: - break; - } - break; - case mCORE_MEMORY_SEARCH_32: - switch (params->type) { - case mCORE_MEMORY_SEARCH_32: - if (core->rawRead32(core, res->address, res->segment) != params->value32) { - mCoreMemorySearchResultsShift(inout, i, 1); - --i; - } - break; - case mCORE_MEMORY_SEARCH_GUESS: + case -1: if (!_testGuess(core, res, params)) { mCoreMemorySearchResultsShift(inout, i, 1); --i;
M
src/platform/qt/MemorySearch.cpp
→
src/platform/qt/MemorySearch.cpp
@@ -41,49 +41,48 @@
QByteArray string; bool ok = false; if (m_ui.typeNum->isChecked()) { + params->type = mCORE_MEMORY_SEARCH_INT; + params->align = -1; if (m_ui.bits8->isChecked()) { - params->type = mCORE_MEMORY_SEARCH_8; + params->width = 1; } if (m_ui.bits16->isChecked()) { - params->type = mCORE_MEMORY_SEARCH_16; + params->width = 2; } if (m_ui.bits32->isChecked()) { - params->type = mCORE_MEMORY_SEARCH_32; + params->width = 4; } if (m_ui.numHex->isChecked()) { uint32_t v = m_ui.value->text().toUInt(&ok, 16); if (ok) { - switch (params->type) { - case mCORE_MEMORY_SEARCH_8: + params->valueInt = v; + switch (params->width) { + case 1: ok = v < 0x100; - params->value8 = v; break; - case mCORE_MEMORY_SEARCH_16: + case 2: ok = v < 0x10000; - params->value16 = v; break; - case mCORE_MEMORY_SEARCH_32: - params->value32 = v; + case 4: break; default: ok = false; + break; } } } if (m_ui.numDec->isChecked()) { uint32_t v = m_ui.value->text().toUInt(&ok, 10); if (ok) { - switch (params->type) { - case mCORE_MEMORY_SEARCH_8: + params->valueInt = v; + switch (params->width) { + case 1: ok = v < 0x100; - params->value8 = v; break; - case mCORE_MEMORY_SEARCH_16: + case 2: ok = v < 0x10000; - params->value16 = v; break; - case mCORE_MEMORY_SEARCH_32: - params->value32 = v; + case 4: break; default: ok = false;@@ -101,6 +100,7 @@ if (m_ui.typeStr->isChecked()) {
params->type = mCORE_MEMORY_SEARCH_STRING; m_string = m_ui.value->text().toLocal8Bit(); params->valueStr = m_string.constData(); + params->width = m_ui.value->text().size(); ok = true; } return ok;@@ -145,61 +145,63 @@ mCoreMemorySearchResult* result = mCoreMemorySearchResultsGetPointer(&m_results, i);
QTableWidgetItem* item = new QTableWidgetItem(QString("%1").arg(result->address, 8, 16, QChar('0'))); m_ui.results->setItem(i, 0, item); QTableWidgetItem* type; - if (m_ui.numHex->isChecked()) { - switch (result->type) { - case mCORE_MEMORY_SEARCH_8: + QByteArray string; + if (result->type == mCORE_MEMORY_SEARCH_INT && m_ui.numHex->isChecked()) { + switch (result->width) { + case 1: item = new QTableWidgetItem(QString("%1").arg(core->rawRead8(core, result->address, result->segment), 2, 16, QChar('0'))); break; - case mCORE_MEMORY_SEARCH_16: + case 2: item = new QTableWidgetItem(QString("%1").arg(core->rawRead16(core, result->address, result->segment), 4, 16, QChar('0'))); break; - case mCORE_MEMORY_SEARCH_GUESS: - case mCORE_MEMORY_SEARCH_32: + case 4: item = new QTableWidgetItem(QString("%1").arg(core->rawRead32(core, result->address, result->segment), 8, 16, QChar('0'))); break; - case mCORE_MEMORY_SEARCH_STRING: - item = new QTableWidgetItem("?"); // TODO } } else { switch (result->type) { - case mCORE_MEMORY_SEARCH_8: - item = new QTableWidgetItem(QString::number(core->rawRead8(core, result->address, result->segment))); - break; - case mCORE_MEMORY_SEARCH_16: - item = new QTableWidgetItem(QString::number(core->rawRead16(core, result->address, result->segment))); - break; - case mCORE_MEMORY_SEARCH_GUESS: - case mCORE_MEMORY_SEARCH_32: - item = new QTableWidgetItem(QString::number(core->rawRead32(core, result->address, result->segment))); + case mCORE_MEMORY_SEARCH_INT: + switch (result->width) { + case 1: + item = new QTableWidgetItem(QString::number(core->rawRead8(core, result->address, result->segment))); + break; + case 2: + item = new QTableWidgetItem(QString::number(core->rawRead16(core, result->address, result->segment))); + break; + case 4: + item = new QTableWidgetItem(QString::number(core->rawRead32(core, result->address, result->segment))); + break; + } break; case mCORE_MEMORY_SEARCH_STRING: - item = new QTableWidgetItem("?"); // TODO + string.reserve(result->width); + for (int i = 0; i < result->width; ++i) { + string.append(core->rawRead8(core, result->address + i, result->segment)); + } + item = new QTableWidgetItem(QLatin1String(string)); // TODO } } QString divisor; if (result->guessDivisor > 1) { - divisor = tr(" (⅟%0×)").arg(result->guessDivisor); + if (result->guessMultiplier > 1) { + divisor = tr(" (%0/%1×)").arg(result->guessMultiplier).arg(result->guessMultiplier); + } else { + divisor = tr(" (⅟%0×)").arg(result->guessDivisor); + } + } else if (result->guessMultiplier > 1) { + divisor = tr(" (%0×)").arg(result->guessMultiplier); } switch (result->type) { - case mCORE_MEMORY_SEARCH_8: - type = new QTableWidgetItem(tr("1 byte%0").arg(divisor)); - break; - case mCORE_MEMORY_SEARCH_16: - type = new QTableWidgetItem(tr("2 bytes%0").arg(divisor)); - break; - case mCORE_MEMORY_SEARCH_GUESS: - case mCORE_MEMORY_SEARCH_32: - type = new QTableWidgetItem(tr("4 bytes%0").arg(divisor)); + case mCORE_MEMORY_SEARCH_INT: + type = new QTableWidgetItem(tr("%1 byte%2").arg(result->width).arg(divisor)); break; case mCORE_MEMORY_SEARCH_STRING: - item = new QTableWidgetItem("?"); // TODO + type = new QTableWidgetItem("string"); } m_ui.results->setItem(i, 1, item); m_ui.results->setItem(i, 2, type); } m_ui.results->sortItems(0); - m_ui.results->resizeColumnsToContents(); - m_ui.results->resizeRowsToContents(); } void MemorySearch::openMemory() {