diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index 89529d06e6..257c54720a 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -18,6 +18,7 @@ #include "Windows/Debugger/Debugger_MemoryDlg.h" #include "Windows/Debugger/DebuggerShared.h" #include "Windows/Debugger/BreakpointWindow.h" +#include "Windows/Debugger/ScanRemoveWindow.h" #include "Windows/main.h" #include "Common/CommonWindows.h" @@ -978,6 +979,13 @@ void CtrlDisAsmView::onMouseUp(WPARAM wParam, LPARAM lParam, int button) NopInstructions(selectRangeStart, selectRangeEnd); redraw(); break; + case ID_DISASM_SCANREMOVE: + { + ScanRemoveWindow srw(wnd, debugger); + if (srw.exec()) { + srw.eval(); + } + } case ID_DISASM_SETPCTOHERE: debugger->setPC(curAddress); redraw(); diff --git a/Windows/Debugger/ScanRemoveWindow.cpp b/Windows/Debugger/ScanRemoveWindow.cpp index efe50a1969..c93fe02adb 100644 --- a/Windows/Debugger/ScanRemoveWindow.cpp +++ b/Windows/Debugger/ScanRemoveWindow.cpp @@ -1,9 +1,7 @@ - #include "ScanRemoveWindow.h" #include "../resource.h" - bool ScanRemoveWindow::GetCheckState(HWND hwnd, int dlgItem) { return SendMessage(GetDlgItem(hwnd, dlgItem), BM_GETCHECK, 0, 0) != 0; } @@ -13,7 +11,7 @@ bool ScanRemoveWindow::fetchDialogData(HWND hwnd) char str[256], errorMessage[512]; PostfixExpression exp; - scan = GetCheckState(hwnd, IDC_SCANREMOVE_SCAN); + scan_ = GetCheckState(hwnd, IDC_SCANREMOVE_SCAN); // Parse the address GetWindowTextA(GetDlgItem(hwnd, IDC_SCANREMOVE_ADDRESS), str, 256); @@ -24,7 +22,7 @@ bool ScanRemoveWindow::fetchDialogData(HWND hwnd) MessageBoxA(hwnd, errorMessage, "Error", MB_OK); return false; } - if (cpu->parseExpression(exp, address) == false) + if (cpu->parseExpression(exp, address_) == false) { snprintf(errorMessage, sizeof(errorMessage), "Invalid expression \"%s\": %s", str, getExpressionError()); MessageBoxA(hwnd, errorMessage, "Error", MB_OK); @@ -40,13 +38,19 @@ bool ScanRemoveWindow::fetchDialogData(HWND hwnd) MessageBoxA(hwnd, errorMessage, "Error", MB_OK); return false; } - if (cpu->parseExpression(exp, size) == false) + if (cpu->parseExpression(exp, size_) == false) { snprintf(errorMessage, sizeof(errorMessage), "Invalid expression \"%s\": %s", str, getExpressionError()); MessageBoxA(hwnd, errorMessage, "Error", MB_OK); return false; } + // Now let's validate the range + if (!Memory::IsValidRange(address_, size_)) { + MessageBoxA(hwnd, "Invalid range", "Error", MB_OK); + return false; + } + return true; } @@ -74,15 +78,15 @@ INT_PTR ScanRemoveWindow::DlgFunc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lP case WM_INITDIALOG: // Set the radiobutton values - SendMessage(GetDlgItem(hwnd, IDC_SCANREMOVE_SCAN), BM_SETCHECK, scan ? BST_CHECKED : BST_UNCHECKED, 0); - SendMessage(GetDlgItem(hwnd, IDC_SCANREMOVE_REMOVE), BM_SETCHECK, scan ? BST_UNCHECKED : BST_CHECKED, 0); + SendMessage(GetDlgItem(hwnd, IDC_SCANREMOVE_SCAN), BM_SETCHECK, scan_ ? BST_CHECKED : BST_UNCHECKED, 0); + SendMessage(GetDlgItem(hwnd, IDC_SCANREMOVE_REMOVE), BM_SETCHECK, scan_ ? BST_UNCHECKED : BST_CHECKED, 0); // Set the text in the textboxes - if (address != -1) { - snprintf(str, sizeof(str), "0x%08X", address); + if (address_ != -1) { + snprintf(str, sizeof(str), "0x%08X", address_); SetWindowTextA(GetDlgItem(hwnd, IDC_SCANREMOVE_ADDRESS), str); } - snprintf(str, sizeof(str), "0x%08X", size); + snprintf(str, sizeof(str), "0x%08X", size_); SetWindowTextA(GetDlgItem(hwnd, IDC_SCANREMOVE_SIZE), str); return TRUE; @@ -93,7 +97,7 @@ INT_PTR ScanRemoveWindow::DlgFunc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lP switch (HIWORD(wParam)) { case BN_CLICKED: - scan = true; + scan_ = true; break; } break; @@ -101,7 +105,7 @@ INT_PTR ScanRemoveWindow::DlgFunc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lP switch (HIWORD(wParam)) { case BN_CLICKED: - scan = false; + scan_ = false; break; } break; @@ -138,5 +142,51 @@ INT_PTR ScanRemoveWindow::DlgFunc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lP } bool ScanRemoveWindow::exec() { - return DialogBoxParam(GetModuleHandle(0), MAKEINTRESOURCE(IDD_BREAKPOINT), parentHwnd, StaticDlgFunc, (LPARAM)this) != 0; + return DialogBoxParam(GetModuleHandle(0), MAKEINTRESOURCE(IDD_SCANREMOVE), parentHwnd, StaticDlgFunc, (LPARAM)this) != 0; +} + +void ScanRemoveWindow::Scan() { + bool insertSymbols = MIPSAnalyst::ScanForFunctions(address_, address_ + size_ - 1, true); + MIPSAnalyst::FinalizeScan(insertSymbols); +} + +void ScanRemoveWindow::Remove() { + u32 func_address = g_symbolMap->GetFunctionStart(address_); + if (func_address == SymbolMap::INVALID_ADDRESS) { + func_address = g_symbolMap->GetNextSymbolAddress(address_, SymbolType::ST_FUNCTION); + } + + u32 counter = 0; + while (func_address < address_ + size_ && func_address != SymbolMap::INVALID_ADDRESS) { + g_symbolMap->RemoveFunction(func_address, true); + ++counter; + func_address = g_symbolMap->GetNextSymbolAddress(address_, SymbolType::ST_FUNCTION); + } + + if (counter) { + MIPSAnalyst::ForgetFunctions(address_, address_ + size_ - 1); + + // The following was copied from hle.func.remove: + g_symbolMap->SortSymbols(); + + MIPSAnalyst::UpdateHashMap(); + MIPSAnalyst::ApplyHashMap(); + + if (g_Config.bFuncReplacements) { + MIPSAnalyst::ReplaceFunctions(); + } + + // Clear cache for branch lines and such. + DisassemblyManager manager; + manager.clear(); + } +} + +void ScanRemoveWindow::eval() { + if (scan_) { + Scan(); + } + else { + Remove(); + } } diff --git a/Windows/Debugger/ScanRemoveWindow.h b/Windows/Debugger/ScanRemoveWindow.h index 753fe95685..e4d8d45b6f 100644 --- a/Windows/Debugger/ScanRemoveWindow.h +++ b/Windows/Debugger/ScanRemoveWindow.h @@ -2,15 +2,23 @@ #include #include "Common/CommonWindows.h" #include "Common/CommonTypes.h" +#include "Core/Config.h" #include "Core/Debugger/DebugInterface.h" +#include "Core/Debugger/SymbolMap.h" +#include "Core/MIPS/MIPSAnalyst.h" +#include "Core/Debugger/DisassemblyManager.h" +#include "Core/MemMap.h" class ScanRemoveWindow { HWND parentHwnd; DebugInterface* cpu; - bool scan; - u32 address; - u32 size; + bool scan_; + u32 address_; + u32 size_; + + void Scan(); + void Remove(); bool GetCheckState(HWND hwnd, int dlgItem); bool fetchDialogData(HWND hwnd); @@ -21,10 +29,11 @@ class ScanRemoveWindow { public: ScanRemoveWindow(HWND parent, DebugInterface* cpu) : cpu(cpu) { parentHwnd = parent; - scan = true; - address = -1; - size = 1; + scan_ = true; + address_ = -1; + size_ = 1; } bool exec(); + void eval(); }; diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 85e33bee8c..fd7edc458e 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -380,6 +380,21 @@ BEGIN PUSHBUTTON "Cancel",IDC_BREAKPOINT_CANCEL,186,98,42,14 END +IDD_SCANREMOVE DIALOGEX 0, 0, 236, 119 +STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Edit" +FONT 8, "MS Shell Dlg", 400, 0, 0x1 +BEGIN + LTEXT "Address",IDC_STATIC,7,8,27,8 + EDITTEXT IDC_SCANREMOVE_ADDRESS,41,7,69,14,ES_AUTOHSCROLL + CONTROL "Scan",IDC_SCANREMOVE_SCAN,"Button",BS_AUTORADIOBUTTON,123,8,36,10 + CONTROL "Remove",IDC_SCANREMOVE_REMOVE,"Button",BS_AUTORADIOBUTTON,170,8,36,10 + LTEXT "Size",IDC_STATIC,7,27,14,8 + EDITTEXT IDC_SCANREMOVE_SIZE,41,25,69,14,ES_AUTOHSCROLL + DEFPUSHBUTTON "OK",IDC_SCANREMOVE_OK,144,98,41,14 + PUSHBUTTON "Cancel",IDC_SCANREMOVE_CANCEL,186,98,42,14 +END + IDD_DUMPMEMORY DIALOGEX 0, 0, 230, 100 STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | WS_SYSMENU CAPTION "Dump memory" @@ -755,6 +770,7 @@ BEGIN MENUITEM "Remove Function", ID_DISASM_REMOVEFUNCTION MENUITEM "Add Function Here", ID_DISASM_ADDFUNCTION MENUITEM "NOP instruction(s)", ID_DISASM_NOPINSTRUCTION + MENUITEM "Scan / remove functions", ID_DISASM_SCANREMOVE END POPUP "reglist" BEGIN diff --git a/Windows/resource.h b/Windows/resource.h index 82e363b816..a38c518527 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -61,6 +61,7 @@ #define IDD_GEDBG_TAB_MATRICES 255 #define IDD_GEDBG_STEPCOUNT 256 #define IDD_CPUWATCH 257 +#define IDD_SCANREMOVE 258 #define IDC_STOPGO 1001 #define IDC_ADDRESS 1002 @@ -352,6 +353,7 @@ #define IDC_DISASM_FMT_INT 40233 #define IDC_DISASM_FMT_FLOAT 40234 #define IDC_DISASM_FMT_STR 40235 +#define ID_DISASM_SCANREMOVE 40236 // Dummy option to let the buffered rendering hotkey cycle through all the options.