Add a memory dump window

This commit is contained in:
Henrik Rydgård committed 2025-01-09 13:14:13 +01:00
1 parent 0881bd6a14
commit 08d251b5bc
5 files changed
+103 -3

No files matched your search

+18
View File
@@ -56,6 +56,12 @@ void ShowInMemoryViewerMenuItem(uint32_t addr, ImControl &control) {
}
}
void ShowInMemoryDumperMenuItem(uint32_t addr, uint32_t size, MemDumpMode mode, ImControl &control) {
if (ImGui::MenuItem(mode == MemDumpMode::Raw ? "Dump bytes to file..." : "Disassemble to file...")) {
control.command = { ImCmd::SHOW_IN_MEMORY_DUMPER, addr, size };
}
}
void ShowInWindowMenuItems(uint32_t addr, ImControl &control) {
// Enable when we implement the memory viewer
ShowInMemoryViewerMenuItem(addr, control);
@@ -1112,6 +1118,7 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu
snprintf(title, sizeof(title), "Memory %d", i + 1);
ImGui::MenuItem(title, nullptr, &cfg_.memViewOpen[i]);
}
ImGui::MenuItem("Memory Dumper", nullptr, &cfg_.memDumpOpen);
ImGui::EndMenu();
}
if (ImGui::BeginMenu("HLE")) {
@@ -1253,6 +1260,10 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu
pixelViewer_.Draw(cfg_, control, gpuDebug, draw);
}
if (cfg_.memDumpOpen) {
memDumpWindow_.Draw(cfg_);
}
for (int i = 0; i < 4; i++) {
if (cfg_.memViewOpen[i]) {
mem_[i].Draw(mipsDebug, cfg_, control, i);
@@ -1288,6 +1299,13 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUDebugInterface *gpuDebu
ImGui::SetWindowFocus(ImMemWindow::Title(index));
break;
}
case ImCmd::SHOW_IN_MEMORY_DUMPER:
{
cfg_.memDumpOpen = true;
memDumpWindow_.SetRange(control.command.param, control.command.param2);
ImGui::SetWindowFocus(memDumpWindow_.Title());
break;
}
case ImCmd::TRIGGER_FIND_POPUP:
// TODO
break;
+4
View File
@@ -143,6 +143,7 @@ struct ImConfig {
bool pixelViewerOpen;
bool npOpen;
bool socketsOpen;
bool memDumpOpen;
bool memViewOpen[4];
// HLE explorer settings
@@ -175,6 +176,7 @@ enum class ImCmd {
SHOW_IN_GE_DISASM,
SHOW_IN_MEMORY_VIEWER, // param is address, param2 is viewer index
SHOW_IN_PIXEL_VIEWER, // param is address, param2 is stride, |0x80000000 if depth, param3 is w/h
SHOW_IN_MEMORY_DUMPER, // param is address, param2 is size, param3 is mode
};
struct ImCommand {
@@ -211,6 +213,7 @@ private:
ImMemWindow mem_[4]; // We support 4 separate instances of the memory viewer.
ImStructViewer structViewer_;
ImGePixelViewerWindow pixelViewer_;
ImMemDumpWindow memDumpWindow_;
ImSnapshotState newSnapshot_;
ImSnapshotState snapshot_;
@@ -226,4 +229,5 @@ private:
void ImClickableAddress(uint32_t addr, ImControl &control, ImCmd cmd);
void ShowInWindowMenuItems(uint32_t addr, ImControl &control);
void ShowInMemoryViewerMenuItem(uint32_t addr, ImControl &control);
void ShowInMemoryDumperMenuItem(uint32_t addr, uint32_t size, MemDumpMode mode, ImControl &control);
void StatusBar(std::string_view str);
+4 -3
View File
@@ -830,9 +830,9 @@ void ImDisasmView::PopupMenu(ImControl &control) {
statusBarText_ = "WARNING: unable to find function symbol here";
}
}
u32 prevBegin = g_symbolMap->GetFunctionStart(curAddress_);
if (ImGui::MenuItem("Add function")) {
char statusBarTextBuff[256];
u32 prevBegin = g_symbolMap->GetFunctionStart(curAddress_);
if (prevBegin != -1) {
if (prevBegin == curAddress_) {
snprintf(statusBarTextBuff, 256, "WARNING: There's already a function entry point at this adress");
@@ -861,8 +861,9 @@ void ImDisasmView::PopupMenu(ImControl &control) {
mapReloaded_ = true;
}
}
if (ImGui::MenuItem("Disassemble to file")) {
disassembleToFile();
if (prevBegin != -1) {
u32 prevSize = g_symbolMap->GetFunctionSize(prevBegin);
ShowInMemoryDumperMenuItem(prevBegin, prevSize, MemDumpMode::Disassembly, control);
}
ImGui::EndPopup();
}
+49
View File
@@ -1,6 +1,7 @@
#include <cctype>
#include <cmath>
#include <iomanip>
#include <cstdio>
#include <sstream>
#include "ext/imgui/imgui.h"
@@ -9,6 +10,7 @@
#include "ext/xxhash.h"
#include "Common/StringUtils.h"
#include "Common/File/FileUtil.h"
#include "Core/Config.h"
#include "Core/MemMap.h"
#include "Core/Reporting.h"
@@ -838,3 +840,50 @@ void ImMemView::setHighlightType(MemBlockFlags flags) {
updateStatusBarText();
}
}
void ImMemDumpWindow::Draw(ImConfig &cfg) {
ImGui::SetNextWindowSize(ImVec2(200, 300), ImGuiCond_FirstUseEver);
if (!ImGui::Begin(Title(), &cfg.memDumpOpen)) {
ImGui::End();
return;
}
if (ImGui::Button("User RAM (0x08800000)")) {
address_ = 0x08800000;
size_ = 0x01800000; // 24MB
}
ImGui::InputScalar("Starting address: ", ImGuiDataType_U32, &address_, NULL, NULL, "%08X");
ImGui::InputScalar("Size: ", ImGuiDataType_U32, &size_, NULL, NULL, "%08X");
ImGui::InputText("Filename: ", filename_, ARRAY_SIZE(filename_));
if (ImGui::Button("Dump!")) {
uint32_t validSize = Memory::ValidSize(address_, size_);
if (validSize != size_) {
errorMsg_ = "Address range out of bounds";
if (Memory::IsValidAddress(address_)) {
size_ = validSize;
}
} else if (strlen(filename_) == 0) {
errorMsg_ = "Please specify a valid filename";
} else {
FILE *file = File::OpenCFile(Path(filename_), "wb");
if (!file) {
errorMsg_ = "Couldn't open file for writing";
} else {
const uint8_t *ptr = Memory::GetPointer(address_);
fwrite(ptr, 1, size_, file);
fclose(file);
errorMsg_.clear();
}
}
}
if (!errorMsg_.empty()) {
ImGui::TextUnformatted(errorMsg_.data(), errorMsg_.data() + errorMsg_.size());
}
ImGui::End();
}
+28
View File
@@ -118,3 +118,31 @@ private:
std::string statusMessage_;
};
enum class MemDumpMode {
Raw = 0,
Disassembly = 1,
};
class ImMemDumpWindow {
public:
ImMemDumpWindow() {
filename_[0] = 0;
address_ = 0x08800000;
size_ = 0x01800000;
}
static const char *Title() {
return "Memory Dumper";
}
void Draw(ImConfig &cfg);
void SetRange(uint32_t addr, uint32_t size) {
address_ = addr;
size_ = size;
}
private:
uint32_t address_;
uint32_t size_;
char filename_[1024];
std::string errorMsg_;
};