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