Debugger: Allow memory access logs to operate read-only

This commit is contained in:
Vicki Pfau 2025-01-15 23:46:20 -08:00
parent 311d9f3550
commit 7012f9c666
5 changed files with 46 additions and 9 deletions

View File

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

View File

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

View File

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

View File

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

View File

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