mirror of https://github.com/mgba-emu/mgba.git
Debugger: Allow memory access logs to operate read-only
This commit is contained in:
parent
311d9f3550
commit
7012f9c666
|
@ -257,6 +257,7 @@ bool mDebuggerIsShutdown(const struct mDebugger*);
|
|||
|
||||
struct mDebuggerModule* mDebuggerCreateModule(enum mDebuggerType type, struct mCore*);
|
||||
void mDebuggerModuleSetNeedsCallback(struct mDebuggerModule*);
|
||||
void mDebuggerModuleClearNeedsCallback(struct mDebuggerModule*);
|
||||
|
||||
bool mDebuggerLookupIdentifier(struct mDebugger* debugger, const char* name, int32_t* value, int* segment);
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ struct mDebuggerAccessLogRegion {
|
|||
uint32_t segmentStart;
|
||||
mDebuggerAccessLogFlags* block;
|
||||
mDebuggerAccessLogFlagsEx* blockEx;
|
||||
ssize_t watchpoint;
|
||||
};
|
||||
|
||||
DECLARE_VECTOR(mDebuggerAccessLogRegionList, struct mDebuggerAccessLogRegion);
|
||||
|
@ -41,6 +42,9 @@ void mDebuggerAccessLoggerDeinit(struct mDebuggerAccessLogger*);
|
|||
bool mDebuggerAccessLoggerOpen(struct mDebuggerAccessLogger*, struct VFile*, int mode);
|
||||
bool mDebuggerAccessLoggerClose(struct mDebuggerAccessLogger*);
|
||||
|
||||
void mDebuggerAccessLoggerStart(struct mDebuggerAccessLogger*);
|
||||
void mDebuggerAccessLoggerStop(struct mDebuggerAccessLogger*);
|
||||
|
||||
int mDebuggerAccessLoggerWatchMemoryBlockId(struct mDebuggerAccessLogger*, size_t id, mDebuggerAccessLogRegionFlags);
|
||||
int mDebuggerAccessLoggerWatchMemoryBlockName(struct mDebuggerAccessLogger*, const char* internalName, mDebuggerAccessLogRegionFlags);
|
||||
|
||||
|
|
|
@ -71,7 +71,6 @@ static void _mDebuggerAccessLoggerEntered(struct mDebuggerModule* debugger, enum
|
|||
|
||||
mDebuggerAccessLogFlags flags = 0;
|
||||
mDebuggerAccessLogFlagsEx flagsEx = 0;
|
||||
int i;
|
||||
switch (reason) {
|
||||
case DEBUGGER_ENTER_WATCHPOINT:
|
||||
switch (info->type.wp.accessSource) {
|
||||
|
@ -257,13 +256,18 @@ static bool _setupRegion(struct mDebuggerAccessLogger* logger, struct mDebuggerA
|
|||
return false;
|
||||
}
|
||||
|
||||
struct mWatchpoint wp = {
|
||||
.segment = -1,
|
||||
.minAddress = region->start,
|
||||
.maxAddress = region->end,
|
||||
.type = WATCHPOINT_RW,
|
||||
};
|
||||
logger->d.p->platform->setWatchpoint(logger->d.p->platform, &logger->d, &wp);
|
||||
if (region->watchpoint < 0) {
|
||||
struct mWatchpoint wp = {
|
||||
.segment = -1,
|
||||
.minAddress = region->start,
|
||||
.maxAddress = region->end,
|
||||
.type = WATCHPOINT_RW,
|
||||
};
|
||||
region->watchpoint = logger->d.p->platform->setWatchpoint(logger->d.p->platform, &logger->d, &wp);
|
||||
}
|
||||
if (region->watchpoint < 0) {
|
||||
return false;
|
||||
}
|
||||
mDebuggerModuleSetNeedsCallback(&logger->d);
|
||||
return true;
|
||||
}
|
||||
|
@ -307,7 +311,7 @@ static bool mDebuggerAccessLoggerLoad(struct mDebuggerAccessLogger* logger) {
|
|||
LOAD_32LE(region->end, 0, &info->end);
|
||||
LOAD_32LE(region->size, 0, &info->size);
|
||||
LOAD_32LE(region->segmentStart, 0, &info->segmentStart);
|
||||
if (!_setupRegion(logger, region, info)) {
|
||||
if (!_mapRegion(logger, region, info)) {
|
||||
mDebuggerAccessLogRegionListClear(&logger->regions);
|
||||
return false;
|
||||
}
|
||||
|
@ -352,6 +356,30 @@ bool mDebuggerAccessLoggerOpen(struct mDebuggerAccessLogger* logger, struct VFil
|
|||
return loaded;
|
||||
}
|
||||
|
||||
void mDebuggerAccessLoggerStart(struct mDebuggerAccessLogger* logger) {
|
||||
size_t i;
|
||||
for (i = 0; i < logger->mapped->header.nRegions; ++i) {
|
||||
struct mDebuggerAccessLogRegionInfo* info = &logger->mapped->regionInfo[i];
|
||||
struct mDebuggerAccessLogRegion* region = mDebuggerAccessLogRegionListGetPointer(&logger->regions, i);
|
||||
if (!_setupRegion(logger, region, info)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void mDebuggerAccessLoggerStop(struct mDebuggerAccessLogger* logger) {
|
||||
size_t i;
|
||||
for (i = 0; i < logger->mapped->header.nRegions; ++i) {
|
||||
struct mDebuggerAccessLogRegion* region = mDebuggerAccessLogRegionListGetPointer(&logger->regions, i);
|
||||
if (region->watchpoint < 0) {
|
||||
continue;
|
||||
}
|
||||
logger->d.p->platform->clearBreakpoint(logger->d.p->platform, region->watchpoint);
|
||||
region->watchpoint = -1;
|
||||
}
|
||||
logger->d.needsCallback = false;
|
||||
}
|
||||
|
||||
static int _mDebuggerAccessLoggerWatchMemoryBlock(struct mDebuggerAccessLogger* logger, const struct mCoreMemoryBlock* block, mDebuggerAccessLogRegionFlags flags) {
|
||||
if (mDebuggerAccessLogRegionListSize(&logger->regions) >= logger->mapped->header.regionCapacity) {
|
||||
return -1;
|
||||
|
@ -423,6 +451,7 @@ static int _mDebuggerAccessLoggerWatchMemoryBlock(struct mDebuggerAccessLogger*
|
|||
region->size = block->size;
|
||||
region->segmentStart = block->segmentStart;
|
||||
region->block = (mDebuggerAccessLogFlags*) ((uintptr_t) logger->backing + fileEnd);
|
||||
region->watchpoint = -1;
|
||||
|
||||
struct mDebuggerAccessLogRegionInfo* info = &logger->mapped->regionInfo[id];
|
||||
STORE_32LE(region->start, 0, &info->start);
|
||||
|
@ -451,6 +480,7 @@ bool mDebuggerAccessLoggerClose(struct mDebuggerAccessLogger* logger) {
|
|||
if (!logger->backing) {
|
||||
return true;
|
||||
}
|
||||
mDebuggerAccessLoggerStop(logger);
|
||||
mDebuggerAccessLogRegionListClear(&logger->regions);
|
||||
logger->backing->unmap(logger->backing, logger->mapped, logger->backing->size(logger->backing));
|
||||
logger->mapped = NULL;
|
||||
|
|
|
@ -93,6 +93,7 @@ void MemoryAccessLogController::start(bool loadExisting, bool logExtra) {
|
|||
LOG(QT, ERROR) << tr("Failed to open memory log file");
|
||||
return;
|
||||
}
|
||||
mDebuggerAccessLoggerStart(&m_logger);
|
||||
|
||||
m_active = true;
|
||||
emit loggingChanged(true);
|
||||
|
|
|
@ -130,6 +130,7 @@ int main(int argc, char** argv) {
|
|||
mDebuggerAccessLoggerInit(&accessLog);
|
||||
mDebuggerAttachModule(&debugger, &accessLog.d);
|
||||
mDebuggerAccessLoggerOpen(&accessLog, vf, O_RDWR);
|
||||
mDebuggerAccessLoggerStart(&accessLog);
|
||||
hasDebugger = true;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue