Add ability to copy function hash from the disassembly view

See #4179
This commit is contained in:
Henrik Rydgård
2026-02-09 19:26:43 +01:00
parent d06e5733a5
commit 330a638281
10 changed files with 56 additions and 17 deletions
+11 -7
View File
@@ -1261,6 +1261,17 @@ skip:
}
}
bool GetAnalyzedFunctionAt(u32 addr, AnalyzedFunction *out) {
std::lock_guard<std::recursive_mutex> guard(functions_lock);
for (auto iter = functions.begin(), end = functions.end(); iter != end; ++iter) {
if (iter->start <= addr && iter->end >= addr) {
*out = *iter;
return true;
}
}
return false;
}
void ReplaceFunctions() {
std::lock_guard<std::recursive_mutex> guard(functions_lock);
@@ -1299,13 +1310,6 @@ skip:
return 0;
}
void SetHashMapFilename(const std::string& filename) {
if (filename.empty())
hashmapFileName = GetSysDirectory(DIRECTORY_SYSTEM) / "knownfuncs.ini";
else
hashmapFileName = Path(filename);
}
void StoreHashMap(Path filename) {
if (filename.empty())
filename = hashmapFileName;
+2
View File
@@ -108,6 +108,8 @@ namespace MIPSAnalyst {
void FinalizeScan(bool insertSymbols);
void ForgetFunctions(u32 startAddr, u32 endAddr);
bool GetAnalyzedFunctionAt(u32 addr, AnalyzedFunction *out);
void LoadBuiltinHashMap();
void LoadHashMap(const Path &filename);
void StoreHashMap(Path filename = Path());
+11
View File
@@ -12,6 +12,7 @@
#include "Core/Debugger/Breakpoints.h"
#include "Core/MIPS/MIPSDebugInterface.h"
#include "Core/MIPS/MIPSTables.h"
#include "Core/MIPS/MIPSAnalyst.h"
#include "Core/Debugger/SymbolMap.h"
#include "Core/MemMap.h"
#include "Common/System/Request.h"
@@ -751,6 +752,16 @@ void ImDisasmView::PopupMenu(ImControl &control) {
if (ImGui::MenuItem("Copy instruction (hex)")) {
CopyInstructions(selectRangeStart_, selectRangeEnd_, CopyInstructionsMode::OPCODES);
}
if (ImGui::MenuItem("Copy function hash")) {
MIPSAnalyst::AnalyzedFunction func;
if (MIPSAnalyst::GetAnalyzedFunctionAt(curAddress_, &func)) {
if (func.hasHash) {
char temp[256];
snprintf(temp, sizeof(temp), "%016llx:%d = %s\n", func.hash, func.size, func.name);
System_CopyStringToClipboard(temp);
}
}
}
ImGui::Separator();
if (ImGui::MenuItem("Set PC to here")) {
+20 -1
View File
@@ -891,10 +891,26 @@ void CtrlDisAsmView::CopyInstructions(u32 startAddr, u32 endAddr, CopyInstructio
delete [] temp;
} else {
std::string disassembly = DisassembleRange(startAddr,endAddr-startAddr, displaySymbols, debugger);
W32Util::CopyTextToClipboard(wnd, disassembly.c_str());
W32Util::CopyTextToClipboard(wnd, disassembly);
}
}
void CtrlDisAsmView::CopyFunctionHash(u32 addr) {
MIPSAnalyst::AnalyzedFunction func;
if (MIPSAnalyst::GetAnalyzedFunctionAt(addr, &func)) {
if (func.hasHash) {
char temp[256];
snprintf(temp, sizeof(temp), "%016llx:%d = %s\n", func.hash, func.size, func.name);
W32Util::CopyTextToClipboard(wnd, temp);
} else {
MessageBox(wnd, L"No hash", L"", 0);
}
} else {
MessageBox(wnd, L"No function", L"", 0);
}
}
void CtrlDisAsmView::NopInstructions(u32 selectRangeStart, u32 selectRangeEnd) {
for (u32 addr = selectRangeStart; addr < selectRangeEnd; addr += 4) {
Memory::Write_U32(0, addr);
@@ -945,6 +961,9 @@ void CtrlDisAsmView::onMouseUp(WPARAM wParam, LPARAM lParam, int button)
case ID_DISASM_COPYINSTRUCTIONHEX:
CopyInstructions(selectRangeStart, selectRangeEnd, CopyInstructionsMode::OPCODES);
break;
case ID_DISASM_COPYFUNCTIONHASH:
CopyFunctionHash(curAddress);
break;
case ID_DISASM_NOPINSTRUCTION:
NopInstructions(selectRangeStart, selectRangeEnd);
redraw();
+1
View File
@@ -75,6 +75,7 @@ class CtrlDisAsmView {
void updateStatusBarText();
void drawBranchLine(HDC hdc, std::map<u32, int> &addressPositions, const BranchLine &line);
void CopyInstructions(u32 startAddr, u32 endAddr, CopyInstructionsMode mode);
void CopyFunctionHash(u32 addr);
void NopInstructions(u32 startAddr, u32 endAddr);
std::set<std::string> getSelectedLineArguments();
void drawArguments(HDC hdc, const DisassemblyLineInfo &line, int x, int y, int textColor, const std::set<std::string> &currentArguments);
+5 -5
View File
@@ -596,7 +596,7 @@ void CtrlMemView::onMouseUp(WPARAM wParam, LPARAM lParam, int button) {
std::ostringstream stream;
stream << (Memory::IsValidAddress(curAddress_) ? Memory::Read_Float(curAddress_) : NAN);
auto temp_string = stream.str();
W32Util::CopyTextToClipboard(wnd, temp_string.c_str());
W32Util::CopyTextToClipboard(wnd, temp_string);
}
break;
@@ -814,7 +814,7 @@ void CtrlMemView::ScrollCursor(int bytes, GotoMode mode) {
redraw();
}
bool CtrlMemView::ParseSearchString(const std::string &query, bool asHex, std::vector<uint8_t> &data) {
bool CtrlMemView::ParseSearchString(std::string_view query, bool asHex, std::vector<uint8_t> &data) {
data.clear();
if (!asHex) {
for (size_t i = 0; i < query.length(); i++) {
@@ -847,7 +847,7 @@ bool CtrlMemView::ParseSearchString(const std::string &query, bool asHex, std::v
return true;
}
std::vector<u32> CtrlMemView::searchString(const std::string &searchQuery) {
std::vector<u32> CtrlMemView::searchString(std::string_view searchQuery) {
std::vector<u32> searchResAddrs;
auto memLock = Memory::Lock();
@@ -993,8 +993,8 @@ void CtrlMemView::setHighlightType(MemBlockFlags flags) {
}
}
uint32_t CtrlMemView::pickTagColor(const std::string &tag) {
uint32_t CtrlMemView::pickTagColor(std::string_view tag) {
int colors[6] = { 0xe0FFFF, 0xFFE0E0, 0xE8E8FF, 0xFFE0FF, 0xE0FFE0, 0xFFFFE0 };
int which = XXH3_64bits(tag.c_str(), tag.length()) % ARRAY_SIZE(colors);
int which = XXH3_64bits(tag.data(), tag.length()) % ARRAY_SIZE(colors);
return colors[which];
}
+3 -3
View File
@@ -41,7 +41,7 @@ public:
MIPSDebugInterface *getDebugger() {
return debugger_;
}
std::vector<u32> searchString(const std::string &searchQuery);
std::vector<u32> searchString(std::string_view query);
void onPaint(WPARAM wParam, LPARAM lParam);
void onVScroll(WPARAM wParam, LPARAM lParam);
void onKeyDown(WPARAM wParam, LPARAM lParam);
@@ -57,10 +57,10 @@ public:
void setHighlightType(MemBlockFlags flags);
private:
bool ParseSearchString(const std::string &query, bool asHex, std::vector<uint8_t> &data);
bool ParseSearchString(std::string_view query, bool asHex, std::vector<uint8_t> &data);
void updateStatusBarText();
void search(bool continueSearch);
uint32_t pickTagColor(const std::string &tag);
uint32_t pickTagColor(std::string_view tag);
enum class GotoMode {
RESET,
+1
View File
@@ -745,6 +745,7 @@ BEGIN
MENUITEM "Copy Address", ID_DISASM_COPYADDRESS
MENUITEM "Copy Instruction (Hex)", ID_DISASM_COPYINSTRUCTIONHEX
MENUITEM "Copy Instruction (Disasm)", ID_DISASM_COPYINSTRUCTIONDISASM
MENUITEM "Copy Function Hash", ID_DISASM_COPYFUNCTIONHASH
MENUITEM "Disassemble to File", ID_DISASM_DISASSEMBLETOFILE
MENUITEM SEPARATOR
MENUITEM "Assemble Opcode", ID_DISASM_ASSEMBLE
+1
View File
@@ -136,6 +136,7 @@
#define ID_MEMVIEW_COPYVALUE_8 40005
#define ID_DISASM_COPYINSTRUCTIONDISASM 40006
#define ID_DISASM_COPYINSTRUCTIONHEX 40007
#define ID_DISASM_COPYFUNCTIONHASH 40031
#define ID_EMULATION_SPEEDLIMIT 40008
#define ID_TOGGLE_BREAK 40009
#define ID_EMULATION_STOP 40010