Per-module symbol save/load, module identity via crc, GetModuleIndex fix

SymbolMap:
- Fix GetModuleIndex(): it only checked the end of an active module's range
  (via activeModuleEnds.upper_bound), never the start, so an address sitting
  in the gap before a module was silently misattributed to it. Added
  GetModuleIndexByName() as a companion lookup.
- AddModule() gains an optional crc param, stored per ModuleEntry. Reactivating
  a module by name now also requires the crc to agree when both sides know it,
  so two unrelated binaries that happen to share a name no longer get merged
  into one symbol table (addresses the old TODO at the top of SymbolMap.h).
- AddLabel()/AddFunction() gain an updateName param (default false, preserving
  existing "first writer wins" behavior) so a trusted source - like a loaded
  symbol file - can be allowed to overwrite a name that a lower-confidence
  automatic pass already assigned.
- New SaveModuleSymbols()/LoadModuleSymbols()/GetModuleSymbolsPath(): save or
  restore one module's functions/data/labels to/from a small human-editable
  text file, addressed relative to the module (so the file stays valid however
  the module ends up positioned on a later run). Keyed by
  PSP/SYSTEM/SYMBOLS/<moduleName>_<crc>.ppsym - deliberately by module+crc
  rather than by game, so it's shared by every game/homebrew that loads the
  exact same module. A "# game <id> <title>" comment records who last saved
  it, informational only.

WebSocket debugger: hle.module.saveSymbols/loadSymbols expose the above.

sceKernelModule.cpp: auto-load a module's saved symbols right after it's
registered with the symbol map (both the real ELF-load path and the
savestate-load path), and auto-save on unload (before UnloadModule(), while
its symbols are still active) - gated behind the new bAutoSaveLoadSymbols
config setting (default off), with a matching Developer Tools checkbox and
a --auto-save-load-symbols command-line override for headless use.

Includes some in-progress cleanup already staged: DescribeAddress now calls
g_symbolMap->GetDescription() directly instead of through the now-removed
MIPSDebugInterface::getDescription() wrapper.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GZq8ZtJmFY7bkX5FVkr3P9
This commit is contained in:
Henrik Rydgård
2026-08-17 16:01:23 +02:00
co-authored by Claude Sonnet 5
parent 2a1df9f0b8
commit 29a38af37e
14 changed files with 458 additions and 40 deletions
+2
View File
@@ -201,6 +201,8 @@ void DeveloperToolsScreen::CreateGeneralTab(UI::LinearLayout *list) {
CheckBox *localDebugger = list->Add(new CheckBox(&g_Config.bRemoteDebuggerLocal, dev->T("Use locally hosted remote debugger")));
localDebugger->SetEnabledPtr(&allowDebugger_);
list->Add(new CheckBox(&g_Config.bAutoSaveLoadSymbols, dev->T("Auto save/load module symbols")));
list->Add(new Choice(dev->T("GPI/GPO switches/LEDs")))->OnClick.Add([=](UI::EventParams &e) {
screenManager()->push(new GPIGPOScreen(dev->T("GPI/GPO switches/LEDs")));
});