Improve DescribeAddress, show the description of the currently selected line in disassembly

This commit is contained in:
Henrik Rydgård committed 2026-08-14 14:38:33 +02:00
1 parent 1ce23df734
commit f5bd302694
12 files changed
+59 -34

No files matched your search

+1 -1
View File
@@ -669,7 +669,7 @@ static ExceptionAction ResolveExceptionAction(ExceptionAction action) {
// straight after an address in a log line, e.g. " [EBOOT.BIN.text+1234]". Empty if no match.
static std::string ModuleAddressSuffix(u32 address) {
char desc[96];
if (DescribeKernelModuleAddress(address, desc, sizeof(desc))) {
if (DescribeModuleAddress(address, desc, sizeof(desc))) {
return std::string(" [") + desc + "]";
} else {
return std::string();
+33
View File
@@ -26,10 +26,12 @@
#include "Common/Serialize/Serializer.h"
#include "Common/Serialize/SerializeFuncs.h"
#include "Common/Thread/ThreadUtil.h"
#include "Common/Data/Text/StringWriter.h"
#include "Core/Config.h"
#include "Core/CoreTiming.h"
#include "Core/Debugger/Breakpoints.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/HLE/sceKernelModule.h" // for DescribeAddress
#include "Core/MIPS/MIPS.h"
#include "Common/StringUtils.h"
@@ -782,3 +784,34 @@ void MemBlockReleaseDetailed() {
bool MemBlockInfoDetailed() {
return g_Config.bDebugMemInfoDetailed || detailedOverride != 0;
}
void DescribeAddress(const MIPSDebugInterface *mips, u32 address, char *buffer, size_t bufferSize) {
StringWriter w(buffer, bufferSize);
const char *kernel = (address & 0x80000000) ? " (kernel)" : "";
const char *uncached = (address & 0x40000000) ? " (uncached)" : "";
char desc[512];
if (!Memory::IsValidAddress(address)) {
if (address == 0xdeadbeef) {
w.C("(deadbeef)");
} else {
w.C("(invalid)");
}
} else if (DescribeModuleAddress(address, desc, sizeof(desc))) {
std::string temp = mips->getDescription(address);
w.F("[%s]%s%s: %s", desc, kernel, uncached, temp.c_str());
} else if (Memory::IsVRAMAddress(address)) {
w.F("[VRAM]%s", uncached); // can't be kernel
} else if (Memory::IsScratchpadAddress(address)) {
w.F("[SCRATCH]%s%s", kernel, uncached);
} else {
// Look up in the memory tracker.
w.F("[RAM]%s%s ", kernel, uncached);
const std::vector<MemBlockInfo> memInfo = FindMemInfo(address, 4);
for (const auto &info : memInfo) {
w.F("%s, ", info.tag.c_str());
}
if (!memInfo.empty()) {
w.Rewind(2); // Remove the last comma
}
}
}
+3
View File
@@ -96,3 +96,6 @@ static inline bool MemBlockInfoDetailed(uint32_t size) {
static inline bool MemBlockInfoDetailed(uint32_t size1, uint32_t size2) {
return size1 >= MEMINFO_MIN_SIZE || size2 >= MEMINFO_MIN_SIZE || MemBlockInfoDetailed();
}
class MIPSDebugInterface;
void DescribeAddress(const MIPSDebugInterface *mips, u32 address, char *buffer, size_t bufferSize);
+1 -1
View File
@@ -2652,7 +2652,7 @@ static u32 sceKernelGetModuleIdList(u32 resultBuffer, u32 resultBufferSize, u32
return hleNoLog(0);
}
bool DescribeKernelModuleAddress(u32 address, char *buffer, size_t bufferSize) {
bool DescribeModuleAddress(u32 address, char *buffer, size_t bufferSize) {
u32 error;
for (SceUID moduleId : loadedModules) {
PSPModule *module = kernelObjects.Get<PSPModule>(moduleId, error);
+1 -1
View File
@@ -240,7 +240,7 @@ bool __KernelLoadExec(MIPSState *mips, const char *filename, u32 paramPtr, std::
bool KernelFindImportByStubAddr(u32 stubAddr, std::string *importModuleName, u32 *nid, std::string *importingModuleName);
// Describes which loaded module (and section within it) an address falls in, e.g. "EBOOT.BIN.text+1234".
// Returns an empty string if the address isn't inside any currently loaded module.
bool DescribeKernelModuleAddress(u32 address, char *buffer, size_t bufferSize);
bool DescribeModuleAddress(u32 address, char *buffer, size_t bufferSize);
int __KernelGPUReplay();
void __KernelReturnFromModuleFunc();
SceUID KernelLoadModule(const std::string &filename, std::string *error_string);
+2 -2
View File
@@ -202,7 +202,7 @@ private:
const DebugInterface *cpu;
};
unsigned int MIPSDebugInterface::readMemory(unsigned int address) {
unsigned int MIPSDebugInterface::readMemory(unsigned int address) const {
if (Memory::IsValidRange(address, 4))
return Memory::ReadUnchecked_Instruction(address).encoding;
return 0;
@@ -250,7 +250,7 @@ int MIPSDebugInterface::getColor(unsigned int address, bool darkMode) const {
}
}
std::string MIPSDebugInterface::getDescription(unsigned int address) {
std::string MIPSDebugInterface::getDescription(unsigned int address) const {
return g_symbolMap->GetDescription(address);
}
+2 -2
View File
@@ -36,9 +36,9 @@ public:
void clearBreakpoint(unsigned int address);
void clearAllBreakpoints();
void toggleBreakpoint(unsigned int address);
unsigned int readMemory(unsigned int address);
unsigned int readMemory(unsigned int address) const;
int getColor(unsigned int address, bool darkMode) const;
std::string getDescription(unsigned int address);
std::string getDescription(unsigned int address) const;
u32 GetGPR32Value(int reg) const override { return cpu->r[reg]; }
float GetFPR32Value(int reg) const { return cpu->f[reg]; }
+1 -1
View File
@@ -323,7 +323,7 @@ std::string FormatStackTrace(const std::vector<MIPSStackWalk::StackFrame> &frame
const u32 frameEntry = frame.entry == 0xFFFFFFFF ? 0 : frame.entry;
std::string desc = g_symbolMap->GetDescription(frame.entry);
char moduleDesc[96];
if (DescribeKernelModuleAddress(frame.entry, moduleDesc, sizeof(moduleDesc))) {
if (DescribeModuleAddress(frame.entry, moduleDesc, sizeof(moduleDesc))) {
str << StringFromFormat("%s [%s] (%08x+%03x, pc: %08x sp: %08x)\n", desc.c_str(), moduleDesc, frameEntry, frame.pc - frameEntry, frame.pc, frame.sp);
} else {
str << StringFromFormat("%s (%08x+%03x, pc: %08x sp: %08x)\n", desc.c_str(), frameEntry, frame.pc - frameEntry, frame.pc, frame.sp);
+1 -1
View File
@@ -312,7 +312,7 @@ bool PortManager::Restore() {
VERBOSE_LOG(Log::Net, "PortManager::Restore()");
if (urls == NULL || urls->controlURL == NULL || urls->controlURL[0] == '\0')
{
if (g_Config.bEnableUPnP) WARN_LOG(Log::Net, "PortManager::Remove - the init was not done !");
if (g_Config.bEnableUPnP) WARN_LOG(Log::Net, "PortManager::Restore - the init was not done !");
return false;
}
for (auto it = m_otherPortList.begin(); it != m_otherPortList.end(); ++it) {
+4 -22
View File
@@ -17,7 +17,6 @@
#include "Core/SaveState.h"
#include "Core/WebServer.h"
#include "Core/Debugger/MemBlockInfo.h"
#include "Core/RetroAchievements.h"
#include "Core/Core.h"
#include "Core/Debugger/DebugInterface.h"
#include "Core/Debugger/DisassemblyManager.h"
@@ -217,26 +216,9 @@ void DrawSchedulerView(ImConfig &cfg) {
ImGui::End();
}
static void DescribeGPRValue(u32 value, char *buffer, size_t bufferSize) {
static void DescribeGPRValue(const MIPSDebugInterface *mipsDebug, u32 value, char *buffer, size_t bufferSize) {
if (Memory::IsValidAddress(value)) {
char moduleName[64];
const char *kernel = (value & 0x80000000) ? " (kernel)" : "";
const char *uncached = (value & 0x40000000) ? " (uncached)" : "";
if (DescribeKernelModuleAddress(value, moduleName, sizeof(moduleName))) {
snprintf(buffer, bufferSize, "[%s]%s%s", moduleName, kernel, uncached);
return;
} else if (Memory::IsVRAMAddress(value)) {
snprintf(buffer, bufferSize, "[VRAM]%s", uncached); // can't be kernel
return;
} else if (Memory::IsScratchpadAddress(value)) {
snprintf(buffer, bufferSize, "[SCRATCH]%s%s", kernel, uncached);
return;
} else {
// TODO: Symbol lookup
snprintf(buffer, bufferSize, "[RAM]%s%s", kernel, uncached);
return;
}
DescribeAddress(mipsDebug, value, buffer, bufferSize);
} else {
snprintf(buffer, bufferSize, "(value)");
}
@@ -292,8 +274,8 @@ static void DrawGPRs(ImConfig &config, ImControl &control, const MIPSDebugInterf
ImGui::Text("%d", value);
}
ImGui::TableNextColumn();
char temp[72];
DescribeGPRValue(value, temp, sizeof(temp));
char temp[256];
DescribeGPRValue(mipsDebug, value, temp, sizeof(temp));
ImGui::TextUnformatted(temp);
if (diff || disabled) {
ImGui::PopStyleColor();
+7 -2
View File
@@ -440,7 +440,7 @@ void ImDisasmView::Draw(ImDrawList *drawList, ImControl &control) {
ImGui_PopFont();
ImGui::OpenPopupOnItemClick("context", ImGuiPopupFlags_MouseButtonRight);
PopupMenu(control);
PopupMenu(currentMIPS, control);
drawList->PopClipRect();
}
@@ -735,7 +735,7 @@ void ImDisasmView::CopyInstructions(u32 startAddr, u32 endAddr, CopyInstructions
}
}
void ImDisasmView::PopupMenu(ImControl &control) {
void ImDisasmView::PopupMenu(MIPSState *mips, ImControl &control) {
bool renameFunctionPopup = false;
if (ImGui::BeginPopup("context")) {
ImGui::Text("Address: %08x", curAddress_);
@@ -1219,6 +1219,11 @@ void ImDisasmWindow::Draw(MIPSDebugInterface *mipsDebug, ImConfig &cfg, ImContro
ImGui::SameLine();
ImGui::TextUnformatted(BreakReasonToString(breakReason));
// Now, the address info line.
char addrDesc[256];
DescribeAddress(mipsDebug, disasmView_.getSelection(), addrDesc, sizeof(addrDesc));
ImGui::Text("%08x: %s", disasmView_.getSelection(), addrDesc);
ImVec2 avail = ImGui::GetContentRegionAvail();
avail.y -= ImGui::GetTextLineHeightWithSpacing();
+3 -1
View File
@@ -16,6 +16,8 @@
struct ImConfig;
struct ImControl;
class MIPSState;
// Corresponds to CtrlDisAsmView
// TODO: Fold out common code.
class ImDisasmView {
@@ -28,7 +30,7 @@ public:
void Draw(ImDrawList *drawList, ImControl &control);
void PopupMenu(ImControl &control);
void PopupMenu(MIPSState *mips, ImControl &control);
void NotifyStep();
void ScrollRelative(int amount);