From b9f5fd1f4418c47b24d142cd2c67cb399404335d Mon Sep 17 00:00:00 2001 From: hrydgard Date: Sun, 24 Aug 2008 20:25:36 +0000 Subject: [PATCH] Very simple call tree browser added to code window, bottom left. git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@298 8ced0084-cf51-0410-be5f-012b33b47a6e --- Externals/Bochs_disasm/PowerPCDisasm.cpp | 8 +- Source/Core/Core/Src/PowerPC/SymbolDB.cpp | 6 ++ Source/Core/DebuggerWX/src/CodeView.cpp | 41 +++++++-- Source/Core/DebuggerWX/src/CodeView.h | 9 +- Source/Core/DebuggerWX/src/CodeWindow.cpp | 105 ++++++++++++++++------ Source/Core/DebuggerWX/src/CodeWindow.h | 10 +++ 6 files changed, 140 insertions(+), 39 deletions(-) diff --git a/Externals/Bochs_disasm/PowerPCDisasm.cpp b/Externals/Bochs_disasm/PowerPCDisasm.cpp index b2b91fcf41..ca7c1854e1 100644 --- a/Externals/Bochs_disasm/PowerPCDisasm.cpp +++ b/Externals/Bochs_disasm/PowerPCDisasm.cpp @@ -491,9 +491,9 @@ namespace PPCDisasm *oper++ = ','; } if (in & 2) /* AA ? */ - sprintf(dp->operands,"0x%.8X",(unsigned long)d); + sprintf(dp->operands,"->0x%.8X",(unsigned long)d); else - sprintf(oper,"0x%.8X",(unsigned long)(*dp->iaddr) + d); + sprintf(oper,"->0x%.8X",(unsigned long)(*dp->iaddr) + d); dp->type = PPCINSTR_BRANCH; dp->displacement = (ppc_word)d; } @@ -507,9 +507,9 @@ namespace PPCDisasm sprintf(dp->opcode,"b%s",b_ext[in&3]); if (in & 2) /* AA ? */ - sprintf(dp->operands,"0x%.8X",(unsigned long)d); + sprintf(dp->operands,"->0x%.8X",(unsigned long)d); else - sprintf(dp->operands,"0x%.8X",(unsigned long)(*dp->iaddr) + d); + sprintf(dp->operands,"->0x%.8X",(unsigned long)(*dp->iaddr) + d); dp->type = PPCINSTR_BRANCH; dp->displacement = (ppc_word)d; } diff --git a/Source/Core/Core/Src/PowerPC/SymbolDB.cpp b/Source/Core/Core/Src/PowerPC/SymbolDB.cpp index 8caf0e542f..80511116ef 100644 --- a/Source/Core/Core/Src/PowerPC/SymbolDB.cpp +++ b/Source/Core/Core/Src/PowerPC/SymbolDB.cpp @@ -138,6 +138,11 @@ const char *SymbolDB::GetDescription(u32 addr) void SymbolDB::FillInCallers() { + for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++) + { + iter->second.callers.clear(); + } + for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++) { Symbol &f = iter->second; @@ -145,6 +150,7 @@ void SymbolDB::FillInCallers() { SCall NewCall(iter->first, f.calls[i].callAddress); u32 FunctionAddress = f.calls[i].function; + XFuncMap::iterator FuncIterator = functions.find(FunctionAddress); if (FuncIterator != functions.end()) { diff --git a/Source/Core/DebuggerWX/src/CodeView.cpp b/Source/Core/DebuggerWX/src/CodeView.cpp index cb2a76a6e7..28c8a6d339 100644 --- a/Source/Core/DebuggerWX/src/CodeView.cpp +++ b/Source/Core/DebuggerWX/src/CodeView.cpp @@ -29,6 +29,7 @@ #include #include +DEFINE_EVENT_TYPE(wxEVT_CODEVIEW_CHANGE); enum { @@ -39,6 +40,7 @@ enum IDM_INSERTBLR, IDM_RUNTOHERE, IDM_JITRESULTS, + IDM_FOLLOWBRANCH, IDM_RENAMESYMBOL, IDM_PATCHALERT, IDM_COPYFUNCTION, @@ -139,6 +141,13 @@ void CCodeView::OnMouseMove(wxMouseEvent& event) event.Skip(true); } +void CCodeView::RaiseEvent() +{ + wxCommandEvent ev(wxEVT_CODEVIEW_CHANGE, GetId()); + ev.SetEventObject(this); + ev.SetInt(selection); + GetEventHandler()->ProcessEvent(ev); +} void CCodeView::OnMouseUpL(wxMouseEvent& event) { @@ -149,10 +158,22 @@ void CCodeView::OnMouseUpL(wxMouseEvent& event) //ReleaseCapture(); redraw(); } - + RaiseEvent(); event.Skip(true); } +u32 CCodeView::AddrToBranch(u32 addr) +{ + const char *temp = debugger->disasm(addr); + const char *mojs = strstr(temp, "->0x"); + if (mojs) + { + u32 dest; + sscanf(mojs+4,"%08x", &dest); + return dest; + } + return 0; +} void CCodeView::OnPopupMenu(wxCommandEvent& event) { @@ -214,6 +235,15 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event) case IDM_JITRESULTS: CJitWindow::ViewAddr(selection); break; + + case IDM_FOLLOWBRANCH: + { + u32 dest = AddrToBranch(selection); + if (dest) + Center(dest); + RaiseEvent(); + } + break; case IDM_RENAMESYMBOL: { @@ -246,17 +276,20 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event) void CCodeView::OnMouseUpR(wxMouseEvent& event) { + bool isSymbol = g_symbolDB.GetSymbolFromAddr(selection) != 0; // popup menu wxMenu menu; //menu.Append(IDM_GOTOINMEMVIEW, "&Goto in mem view"); + menu.Append(IDM_FOLLOWBRANCH, wxString::FromAscii("&Follow branch"))->Enable(AddrToBranch(selection) ? true : false); + menu.AppendSeparator(); #if wxUSE_CLIPBOARD menu.Append(IDM_COPYADDRESS, wxString::FromAscii("Copy &address")); - menu.Append(IDM_COPYFUNCTION, wxString::FromAscii("Copy &function")); + menu.Append(IDM_COPYFUNCTION, wxString::FromAscii("Copy &function"))->Enable(isSymbol); menu.Append(IDM_COPYCODE, wxString::FromAscii("Copy &code line")); menu.Append(IDM_COPYHEX, wxString::FromAscii("Copy &hex")); menu.AppendSeparator(); #endif - menu.Append(IDM_RENAMESYMBOL, wxString::FromAscii("Rename &symbol")); + menu.Append(IDM_RENAMESYMBOL, wxString::FromAscii("Rename &symbol"))->Enable(isSymbol); menu.AppendSeparator(); menu.Append(IDM_RUNTOHERE, _T("&Run To Here")); menu.Append(IDM_JITRESULTS, wxString::FromAscii("PPC vs X86")); @@ -373,8 +406,6 @@ void CCodeView::OnPaint(wxPaintEvent& event) found = true; } } - - if (!found) { mojs = 0; diff --git a/Source/Core/DebuggerWX/src/CodeView.h b/Source/Core/DebuggerWX/src/CodeView.h index 506dcb2c99..0ff8c696d7 100644 --- a/Source/Core/DebuggerWX/src/CodeView.h +++ b/Source/Core/DebuggerWX/src/CodeView.h @@ -24,11 +24,12 @@ #include +DECLARE_EVENT_TYPE(wxEVT_CODEVIEW_CHANGE, -1); + class CCodeView : public wxControl { public: - CCodeView(DebugInterface* debuginterface, wxWindow* parent, wxWindowID Id = -1, const wxSize& Size = wxDefaultSize); wxSize DoGetBestSize() const; void OnPaint(wxPaintEvent& event); @@ -39,21 +40,21 @@ class CCodeView void OnMouseUpR(wxMouseEvent& event); void OnPopupMenu(wxCommandEvent& event); - u32 GetSelection() {return(selection);} - void Center(u32 addr) { curAddress = addr; + selection = addr; redraw(); } - private: + void RaiseEvent(); int YToAddress(int y); + u32 AddrToBranch(u32 addr); void redraw() {Refresh();} diff --git a/Source/Core/DebuggerWX/src/CodeWindow.cpp b/Source/Core/DebuggerWX/src/CodeWindow.cpp index eb73f7112d..02c6adde10 100644 --- a/Source/Core/DebuggerWX/src/CodeWindow.cpp +++ b/Source/Core/DebuggerWX/src/CodeWindow.cpp @@ -67,6 +67,8 @@ static const long TOOLBAR_STYLE = wxTB_FLAT | wxTB_DOCKABLE | wxTB_TEXT; BEGIN_EVENT_TABLE(CCodeWindow, wxFrame) EVT_LISTBOX(IDM_SYMBOLLIST, CCodeWindow::OnSymbolListChange) EVT_LISTBOX(IDM_CALLSTACKLIST, CCodeWindow::OnCallstackListChange) + EVT_LISTBOX(IDM_CALLERSLIST, CCodeWindow::OnCallersListChange) + EVT_LISTBOX(IDM_CALLSLIST, CCodeWindow::OnCallsListChange) EVT_HOST_COMMAND(wxID_ANY, CCodeWindow::OnHostMessage) EVT_MENU(IDM_LOGWINDOW, CCodeWindow::OnToggleLogWindow) EVT_MENU(IDM_REGISTERWINDOW, CCodeWindow::OnToggleRegisterWindow) @@ -90,6 +92,8 @@ BEGIN_EVENT_TABLE(CCodeWindow, wxFrame) EVT_MENU(IDM_SETPC, CCodeWindow::OnCodeStep) EVT_MENU(IDM_GOTOPC, CCodeWindow::OnCodeStep) EVT_TEXT(IDM_ADDRBOX, CCodeWindow::OnAddrBoxChange) + + EVT_COMMAND(IDM_CODEVIEW, wxEVT_CODEVIEW_CHANGE, CCodeWindow::OnCodeViewChange) END_EVENT_TABLE() #define wxGetBitmapFromMemory(name) _wxGetBitmapFromMemory(name, sizeof(name)) @@ -175,12 +179,14 @@ void CCodeWindow::CreateGUIControls(const SCoreStartupParameter& _LocalCoreStart DebugInterface* di = new PPCDebugInterface(); - codeview = new CCodeView(di, this, wxID_ANY); + codeview = new CCodeView(di, this, IDM_CODEVIEW); sizerBig->Add(sizerLeft, 2, wxEXPAND); sizerBig->Add(codeview, 5, wxEXPAND); sizerLeft->Add(callstack = new wxListBox(this, IDM_CALLSTACKLIST, wxDefaultPosition, wxSize(90, 100)), 0, wxEXPAND); sizerLeft->Add(symbols = new wxListBox(this, IDM_SYMBOLLIST, wxDefaultPosition, wxSize(90, 100), 0, NULL, wxLB_SORT), 1, wxEXPAND); + sizerLeft->Add(calls = new wxListBox(this, IDM_CALLSLIST, wxDefaultPosition, wxSize(90, 100), 0, NULL, wxLB_SORT), 0, wxEXPAND); + sizerLeft->Add(callers = new wxListBox(this, IDM_CALLERSLIST, wxDefaultPosition, wxSize(90, 100), 0, NULL, wxLB_SORT), 0, wxEXPAND); SetSizer(sizerBig); @@ -283,11 +289,6 @@ bool CCodeWindow::UseDualCore() } -void CCodeWindow::JumpToAddress(u32 _Address) -{ - codeview->Center(_Address); -} - void CCodeWindow::OnJitMenu(wxCommandEvent& event) { switch (event.GetId()) @@ -378,7 +379,7 @@ void CCodeWindow::OnCodeStep(wxCommandEvent& event) case IDM_DEBUG_GO: { // [F|RES] prolly we should disable the other buttons in go mode too ... - codeview->Center(PC); + JumpToAddress(PC); if (CCPU::IsStepping()) { @@ -414,7 +415,7 @@ void CCodeWindow::OnCodeStep(wxCommandEvent& event) break; case IDM_GOTOPC: - codeview->Center(PC); + JumpToAddress(PC); break; } @@ -422,21 +423,85 @@ void CCodeWindow::OnCodeStep(wxCommandEvent& event) } +void CCodeWindow::JumpToAddress(u32 _Address) +{ + codeview->Center(_Address); + UpdateLists(); +} + + +void CCodeWindow::UpdateLists() +{ + callers->Clear(); + u32 addr = codeview->GetSelection(); + Symbol *symbol = g_symbolDB.GetSymbolFromAddr(addr); + if (!symbol) + return; + for (int i = 0; i < symbol->callers.size(); i++) + { + u32 caller_addr = symbol->callers[i].callAddress; + Symbol *caller_symbol = g_symbolDB.GetSymbolFromAddr(caller_addr); + int idx = callers->Append(StringFromFormat("< %s (%08x)", caller_symbol->name.c_str(), caller_addr).c_str()); + callers->SetClientData(idx, (void*)caller_addr); + } + + calls->Clear(); + for (int i = 0; i < symbol->calls.size(); i++) + { + u32 call_addr = symbol->calls[i].function; + Symbol *call_symbol = g_symbolDB.GetSymbolFromAddr(call_addr); + int idx = calls->Append(StringFromFormat("> %s (%08x)", call_symbol->name.c_str(), call_addr).c_str()); + calls->SetClientData(idx, (void*)call_addr); + } +} + + +void CCodeWindow::OnCodeViewChange(wxCommandEvent &event) +{ + //PanicAlert("boo"); + UpdateLists(); +} + void CCodeWindow::OnAddrBoxChange(wxCommandEvent& event) { wxTextCtrl* pAddrCtrl = (wxTextCtrl*)GetToolBar()->FindControl(IDM_ADDRBOX); wxString txt = pAddrCtrl->GetValue(); - if (txt.size() == 8) + std::string text(txt.c_str()); + text = StripSpaces(text); + if (text.size() == 8) { u32 addr; - sscanf(txt.mb_str(), "%08x", &addr); - codeview->Center(addr); + sscanf(text.c_str(), "%08x", &addr); + JumpToAddress(addr); } event.Skip(1); } +void CCodeWindow::OnCallstackListChange(wxCommandEvent& event) +{ + int index = callstack->GetSelection(); + u32 address = (u32)(u64)(callstack->GetClientData(index)); + if (address) + JumpToAddress(address); +} + +void CCodeWindow::OnCallersListChange(wxCommandEvent& event) +{ + int index = callers->GetSelection(); + u32 address = (u32)(u64)(callers->GetClientData(index)); + if (address) + JumpToAddress(address); +} + +void CCodeWindow::OnCallsListChange(wxCommandEvent& event) +{ + int index = calls->GetSelection(); + u32 address = (u32)(u64)(calls->GetClientData(index)); + if (address) + JumpToAddress(address); +} void CCodeWindow::Update() { @@ -465,9 +530,9 @@ void CCodeWindow::Update() void CCodeWindow::NotifyMapLoaded() { + g_symbolDB.FillInCallers(); symbols->Show(false); // hide it for faster filling symbols->Clear(); - for (SymbolDB::XFuncMap::iterator iter = g_symbolDB.GetIterator(); iter != g_symbolDB.End(); iter++) { int idx = symbols->Append(wxString::FromAscii(iter->second.name.c_str())); @@ -519,7 +584,7 @@ void CCodeWindow::OnSymbolListChange(wxCommandEvent& event) if (pSymbol != NULL) { - codeview->Center(pSymbol->address); + JumpToAddress(pSymbol->address); } } @@ -529,18 +594,6 @@ void CCodeWindow::OnSymbolListContextMenu(wxContextMenuEvent& event) } -void CCodeWindow::OnCallstackListChange(wxCommandEvent& event) -{ - int index = callstack->GetSelection(); - u32 address = (u32)(u64)(callstack->GetClientData(index)); - - if (address != 0x00) - { - codeview->Center(address); - } -} - - void CCodeWindow::OnToggleLogWindow(wxCommandEvent& event) { if (IsLoggingActivated()) @@ -774,7 +827,7 @@ void CCodeWindow::SingleCPUStep() // sync_event.Wait(); wxThread::Sleep(20); // need a short wait here - codeview->Center(PC); + JumpToAddress(PC); Update(); Host_UpdateLogDisplay(); } diff --git a/Source/Core/DebuggerWX/src/CodeWindow.h b/Source/Core/DebuggerWX/src/CodeWindow.h index e90a589cdd..ec0d083ffe 100644 --- a/Source/Core/DebuggerWX/src/CodeWindow.h +++ b/Source/Core/DebuggerWX/src/CodeWindow.h @@ -55,6 +55,7 @@ class CCodeWindow void Update(); void NotifyMapLoaded(); + bool UseInterpreter(); bool UseDualCore(); void JumpToAddress(u32 _Address); @@ -64,6 +65,7 @@ class CCodeWindow enum { ID_TOOLBAR = 500, + IDM_CODEVIEW, IDM_DEBUG_GO, IDM_STEP, IDM_STEPOVER, @@ -72,6 +74,8 @@ class CCodeWindow IDM_GOTOPC, IDM_ADDRBOX, IDM_CALLSTACKLIST, + IDM_CALLERSLIST, + IDM_CALLSLIST, IDM_SYMBOLLIST, IDM_INTERPRETER, IDM_DUALCORE, @@ -112,6 +116,8 @@ class CCodeWindow CCodeView* codeview; wxListBox* callstack; wxListBox* symbols; + wxListBox* callers; + wxListBox* calls; Common::Event sync_event; wxBitmap m_Bitmaps[Bitmaps_max]; @@ -121,7 +127,10 @@ class CCodeWindow void OnSymbolListChange(wxCommandEvent& event); void OnSymbolListContextMenu(wxContextMenuEvent& event); void OnCallstackListChange(wxCommandEvent& event); + void OnCallersListChange(wxCommandEvent& event); + void OnCallsListChange(wxCommandEvent& event); void OnCodeStep(wxCommandEvent& event); + void OnCodeViewChange(wxCommandEvent &event); void SingleCPUStep(); @@ -138,6 +147,7 @@ class CCodeWindow void CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParameter); void UpdateButtonStates(); + void UpdateLists(); void RecreateToolbar(); void PopulateToolbar(wxToolBar* toolBar);