From 26c4f57691460f7fd5791f32de426752a8bfd7c4 Mon Sep 17 00:00:00 2001 From: Kingcom Date: Wed, 26 Jun 2013 21:49:15 +0200 Subject: [PATCH] Shortcuts for the disassembly view, step over extended, fixes --- Core/Debugger/Breakpoints.cpp | 2 + Windows/Debugger/CtrlDisAsmView.cpp | 60 ++++++++++++++++++++++++--- Windows/Debugger/Debugger_Disasm.cpp | 55 ++++++++++++++++++++++-- Windows/Debugger/Debugger_Disasm.h | 1 + Windows/debugger.txt | 28 +++++++++++++ Windows/ppsspp.rc | Bin 40042 -> 40062 bytes 6 files changed, 138 insertions(+), 8 deletions(-) create mode 100644 Windows/debugger.txt diff --git a/Core/Debugger/Breakpoints.cpp b/Core/Debugger/Breakpoints.cpp index e363e34892..3d74be9b45 100644 --- a/Core/Debugger/Breakpoints.cpp +++ b/Core/Debugger/Breakpoints.cpp @@ -77,6 +77,7 @@ void CBreakPoints::RemoveBreakPoint(u32 _iAddress) { m_iBreakPoints.remove(m_iBreakPoints[i]); InvalidateJit(_iAddress); + host->UpdateDisassembly(); // redraw in order to not show the breakpoint anymore break; } } @@ -130,6 +131,7 @@ void CBreakPoints::AddBreakPoint(u32 _iAddress, bool temp) m_iBreakPoints.insert(pt); InvalidateJit(_iAddress); + host->UpdateDisassembly(); // redraw in order to show the breakpoint } } diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index 84374ffbfd..1a3bc24003 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -88,10 +88,13 @@ LRESULT CALLBACK CtrlDisAsmView::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPA case WM_KEYDOWN: ccp->onKeyDown(wParam,lParam); break; + case WM_SYSKEYDOWN: + ccp->onKeyDown(wParam,lParam); + return 0; // return a value so that windows doesn't execute the standard syskey action case WM_KEYUP: ccp->onKeyUp(wParam,lParam); break; - case WM_LBUTTONDOWN: SetFocus(hwnd); lmbDown=true; ccp->onMouseDown(wParam,lParam,1); break; + case WM_LBUTTONDOWN: lmbDown=true; ccp->onMouseDown(wParam,lParam,1); break; case WM_RBUTTONDOWN: rmbDown=true; ccp->onMouseDown(wParam,lParam,2); break; case WM_MOUSEMOVE: ccp->onMouseMove(wParam,lParam,(lmbDown?1:0) | (rmbDown?2:0)); break; case WM_LBUTTONUP: lmbDown=false; ccp->onMouseUp(wParam,lParam,1); break; @@ -106,7 +109,23 @@ LRESULT CALLBACK CtrlDisAsmView::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPA ccp->redraw(); break; case WM_GETDLGCODE: - return DLGC_WANTARROWS|DLGC_WANTTAB; + if (lParam && ((MSG*)lParam)->message == WM_KEYDOWN) + { + switch (wParam) + { + case VK_LEFT: + case VK_RIGHT: + case VK_UP: + case VK_DOWN: + case VK_F9: + case VK_F10: + case VK_F11: + case VK_TAB: + return DLGC_WANTMESSAGE; + default: + return 0; + } + } break; default: break; @@ -542,6 +561,21 @@ void CtrlDisAsmView::onKeyDown(WPARAM wParam, LPARAM lParam) case VK_CONTROL: controlHeld = true; break; + case VK_F9: + if (debugger->GetPC() != curAddress) + { + SendMessage(GetParent(wnd),WM_USER+3,curAddress,0); + } + break; + case VK_F10: + SendMessage(GetParent(wnd),WM_COMMAND,IDC_STEPOVER,0); + return; + case VK_F11: + SendMessage(GetParent(wnd),WM_COMMAND,IDC_STEP,0); + return; + case VK_SPACE: + debugger->toggleBreakpoint(curAddress); + break; default: return; } @@ -577,13 +611,14 @@ void CtrlDisAsmView::onMouseDown(WPARAM wParam, LPARAM lParam, int button) int newAddress = yToAddress(y); if (button == 1) { - if (newAddress == curAddress) + if (newAddress == curAddress && hasFocus) { debugger->toggleBreakpoint(curAddress); } } curAddress = newAddress; + SetFocus(wnd); redraw(); } @@ -702,8 +737,10 @@ void CtrlDisAsmView::search(bool continueSearch) if (continueSearch == false || searchQuery[0] == 0) { - if (InputBox_GetString(MainWindow::GetHInstance(),MainWindow::GetHWND(),"Search for:","",searchQuery) == false) + if (InputBox_GetString(MainWindow::GetHInstance(),MainWindow::GetHWND(),"Search for:","",searchQuery) == false + || searchQuery[0] == 0) { + SetFocus(wnd); return; } @@ -717,9 +754,18 @@ void CtrlDisAsmView::search(bool continueSearch) searchAddress = matchAddress+instructionSize; } + // limit address to sensible ranges + if (searchAddress < 0x04000000) searchAddress = 0x04000000; + if (searchAddress >= 0x04200000 && searchAddress < 0x08000000) searchAddress = 0x08000000; + if (searchAddress >= 0x0A000000) + { + MessageBox(wnd,"Not found","Search",MB_OK); + return; + } + searching = true; redraw(); // so the cursor is disabled - while (searchAddress < 0xFFFFFFFC) // there should probably be a more intelligent limitation + while (searchAddress < 0x0A000000) { char addressText[64],opcode[64],arguments[256]; const char *dis = debugger->disasm(searchAddress, instructionSize); @@ -754,7 +800,11 @@ void CtrlDisAsmView::search(bool continueSearch) } searchAddress += instructionSize; + if (searchAddress >= 0x04200000 && searchAddress < 0x08000000) searchAddress = 0x08000000; } + + MessageBox(wnd,"Not found","Search",MB_OK); + searching = false; } void CtrlDisAsmView::disassembleToFile() diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index 64e775ae7a..a70bbbac8f 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -182,6 +182,11 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) case IDC_GO: { + // invalidate jit before continuing, so that any breakpoint changes + // can take effect. It's a workaround for temporary breakpoints not + // getting disabled correctly when they trigger. + CBreakPoints::InvalidateJit(); + Sleep(1); SetDebugMode(false); Core_EnableStepping(false); } @@ -200,12 +205,48 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) case IDC_STEPOVER: { + const char* dis = cpu->disasm(cpu->GetPC(),4); + const char* pos = strstr(dis,"->$"); + const char* reg = strstr(dis,"->"); + + u32 breakpointAddress = cpu->GetPC()+cpu->getInstructionSize(0); + if (memcmp(dis,"jal\t",4) == 0) + { + // it's a function call with a delay slot - skip that too + breakpointAddress += cpu->getInstructionSize(0); + } else if (memcmp(dis,"j\t",2) == 0 || memcmp(dis,"b\t",2) == 0) + { + // in case of absolute branches, set the breakpoint at the branch target + sscanf(pos+3,"%08x",&breakpointAddress); + } else if (memcmp(dis,"jr\t",3) == 0) + { + // the same for jumps to registers + int regNum = -1; + for (int i = 0; i < 32; i++) + { + if (stricmp(reg+2,cpu->GetRegName(0,i)) == 0) + { + regNum = i; + break; + } + } + if (regNum == -1) break; + breakpointAddress = cpu->GetRegValue(0,regNum); + } else if (pos != NULL || pos != NULL) + { + // these are all sorts of conditional branches. I'm not sure what to do + // for them. It would have to be evaluated if the branch is taken or not. + // I'll ignore these cases for now. + MessageBox(m_hDlg,"Step over not supported\nfor conditional branches yet!","Sorry",MB_OK); + break; + } + SetDebugMode(false); - CBreakPoints::AddBreakPoint(cpu->GetPC()+cpu->getInstructionSize(0),true); + CBreakPoints::AddBreakPoint(breakpointAddress,true); _dbg_update_(); Core_EnableStepping(false); Sleep(1); - ptr->gotoPC(); + ptr->gotoAddr(breakpointAddress); UpdateDialog(); } break; @@ -347,7 +388,15 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) case WM_USER+1: NotifyMapLoaded(); break; - + case WM_USER+3: // run to wparam + { + CtrlDisAsmView *ptr = CtrlDisAsmView::getFrom(GetDlgItem(m_hDlg,IDC_DISASMVIEW)); + SetDebugMode(false); + CBreakPoints::AddBreakPoint(wParam,true); + _dbg_update_(); + Core_EnableStepping(false); + break; + } case WM_SIZE: { UpdateSize(LOWORD(lParam), HIWORD(lParam)); diff --git a/Windows/Debugger/Debugger_Disasm.h b/Windows/Debugger/Debugger_Disasm.h index 398fea1a92..ee6c6a1e28 100644 --- a/Windows/Debugger/Debugger_Disasm.h +++ b/Windows/Debugger/Debugger_Disasm.h @@ -34,6 +34,7 @@ public: // --- tools --- // // Update Dialog + virtual void Update() { UpdateDialog(true); }; void UpdateDialog(bool _bComplete = false); // SetDebugMode void SetDebugMode(bool _bDebug); diff --git a/Windows/debugger.txt b/Windows/debugger.txt new file mode 100644 index 0000000000..801918350d --- /dev/null +++ b/Windows/debugger.txt @@ -0,0 +1,28 @@ +################# +Disassembly view +################# + +You can change the cursor with the up/down arrow keys, the mouse wheel or by clicking on a line. You can scroll by a whole page with page up/down. Clicking on the cursor will toggle a breakpoint at that position. Addresses in opcodes are replaced by a label if there is one for the respective address. +The PC is highlighted by a square left of the opcode. The background is also slighly brighter. + +Key bindings: +-TAB toggles between display symbols and displaying addresses + hexadecimal representation of each instruction +-F9 sets a temporary breakpoint at the cursor address and starts the cpu (Run to cursor) +-F10 Step Over, will execute until the next line, or the next but one in case of a branch. For absolute branches, it will execute until the branch target. Does not work with conditional branches yet. +-F11 Step Into, will execute the next opcode and then stop +-Space will also toggle the breakpoint at the cursor +-the right arrow key follows a branch +-the left arrow key undoes one level of following. If there is nothing to un-follow, it will jump to the PC +-Ctrl+S will start a text search. It will search through the displayed text until it matches the entered text or reaches the end of the user memory. Escape can be used to cancel the search. Any gaps on screen are represented by a single space, ie "addiu a0". The search starts on the first instruction after the cursor +-Ctrl+C will continue the previous search +-Ctrl+X will disassemble to a file you specify. First you enter the size (in bytes, hexadecimal) of the code to be disassembled, then you select a file name. It will start at the cursor + +########### +Memory View +########### + +The lines are always 16 byte aligned. You can click anywhere on screen or use the arrow keys to move the cursor. You can also use the mouse wheel or the page up/down keys for scrolling. +The active column will have a blue cursor, the inactive one a grey one. +In the hex column, the currently selected nibble is underlined. You can type A-F and 0-9 to change the data. Using the left and right arrow keys in the hex column will move the cursor one nibble at a time. +In the ascii column, you can type all letters to change the data. +Double clicking on an entry in the list will move the cursor to that position. Hitting enter in the goto edit box will do the same. \ No newline at end of file diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index e7ad8ff99e34fd7fb8b162929e3ef3fb778f7751..198d3da4bab6f93c7203ce7c2e83998c5008c202 100644 GIT binary patch delta 163 zcmaF0gX!N6rVT%Ym<<_>CL2zXom^0$HrYd;gEm7DLn=cFLn%WML*8Wn zR^`nB*d?rGT|9F E06{u05&!@I delta 151 zcmeyjgXz@{rVT%Y7%e9+P-4)TJh4W8b4GcV1iJ@ADnk)N>g0nNs*@9XMJ9_) yuu%?XNM$HtP+;(5NM)!1vw|5)7!nyu7*ZK>8B!VY7)mA|%n%2u-#lZ&Gj0HmeJ-&8