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
This commit is contained in:
hrydgard 2008-08-24 20:25:36 +00:00
parent 1b1f0ecae9
commit b9f5fd1f44
6 changed files with 140 additions and 39 deletions

View File

@ -491,9 +491,9 @@ namespace PPCDisasm
*oper++ = ','; *oper++ = ',';
} }
if (in & 2) /* AA ? */ if (in & 2) /* AA ? */
sprintf(dp->operands,"0x%.8X",(unsigned long)d); sprintf(dp->operands,"->0x%.8X",(unsigned long)d);
else else
sprintf(oper,"0x%.8X",(unsigned long)(*dp->iaddr) + d); sprintf(oper,"->0x%.8X",(unsigned long)(*dp->iaddr) + d);
dp->type = PPCINSTR_BRANCH; dp->type = PPCINSTR_BRANCH;
dp->displacement = (ppc_word)d; dp->displacement = (ppc_word)d;
} }
@ -507,9 +507,9 @@ namespace PPCDisasm
sprintf(dp->opcode,"b%s",b_ext[in&3]); sprintf(dp->opcode,"b%s",b_ext[in&3]);
if (in & 2) /* AA ? */ if (in & 2) /* AA ? */
sprintf(dp->operands,"0x%.8X",(unsigned long)d); sprintf(dp->operands,"->0x%.8X",(unsigned long)d);
else 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->type = PPCINSTR_BRANCH;
dp->displacement = (ppc_word)d; dp->displacement = (ppc_word)d;
} }

View File

@ -138,6 +138,11 @@ const char *SymbolDB::GetDescription(u32 addr)
void SymbolDB::FillInCallers() 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++) for (XFuncMap::iterator iter = functions.begin(); iter != functions.end(); iter++)
{ {
Symbol &f = iter->second; Symbol &f = iter->second;
@ -145,6 +150,7 @@ void SymbolDB::FillInCallers()
{ {
SCall NewCall(iter->first, f.calls[i].callAddress); SCall NewCall(iter->first, f.calls[i].callAddress);
u32 FunctionAddress = f.calls[i].function; u32 FunctionAddress = f.calls[i].function;
XFuncMap::iterator FuncIterator = functions.find(FunctionAddress); XFuncMap::iterator FuncIterator = functions.find(FunctionAddress);
if (FuncIterator != functions.end()) if (FuncIterator != functions.end())
{ {

View File

@ -29,6 +29,7 @@
#include <wx/clipbrd.h> #include <wx/clipbrd.h>
#include <wx/textdlg.h> #include <wx/textdlg.h>
DEFINE_EVENT_TYPE(wxEVT_CODEVIEW_CHANGE);
enum enum
{ {
@ -39,6 +40,7 @@ enum
IDM_INSERTBLR, IDM_INSERTBLR,
IDM_RUNTOHERE, IDM_RUNTOHERE,
IDM_JITRESULTS, IDM_JITRESULTS,
IDM_FOLLOWBRANCH,
IDM_RENAMESYMBOL, IDM_RENAMESYMBOL,
IDM_PATCHALERT, IDM_PATCHALERT,
IDM_COPYFUNCTION, IDM_COPYFUNCTION,
@ -139,6 +141,13 @@ void CCodeView::OnMouseMove(wxMouseEvent& event)
event.Skip(true); 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) void CCodeView::OnMouseUpL(wxMouseEvent& event)
{ {
@ -149,10 +158,22 @@ void CCodeView::OnMouseUpL(wxMouseEvent& event)
//ReleaseCapture(); //ReleaseCapture();
redraw(); redraw();
} }
RaiseEvent();
event.Skip(true); 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) void CCodeView::OnPopupMenu(wxCommandEvent& event)
{ {
@ -214,6 +235,15 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
case IDM_JITRESULTS: case IDM_JITRESULTS:
CJitWindow::ViewAddr(selection); CJitWindow::ViewAddr(selection);
break; break;
case IDM_FOLLOWBRANCH:
{
u32 dest = AddrToBranch(selection);
if (dest)
Center(dest);
RaiseEvent();
}
break;
case IDM_RENAMESYMBOL: case IDM_RENAMESYMBOL:
{ {
@ -246,17 +276,20 @@ void CCodeView::OnPopupMenu(wxCommandEvent& event)
void CCodeView::OnMouseUpR(wxMouseEvent& event) void CCodeView::OnMouseUpR(wxMouseEvent& event)
{ {
bool isSymbol = g_symbolDB.GetSymbolFromAddr(selection) != 0;
// popup menu // popup menu
wxMenu menu; wxMenu menu;
//menu.Append(IDM_GOTOINMEMVIEW, "&Goto in mem view"); //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 #if wxUSE_CLIPBOARD
menu.Append(IDM_COPYADDRESS, wxString::FromAscii("Copy &address")); 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_COPYCODE, wxString::FromAscii("Copy &code line"));
menu.Append(IDM_COPYHEX, wxString::FromAscii("Copy &hex")); menu.Append(IDM_COPYHEX, wxString::FromAscii("Copy &hex"));
menu.AppendSeparator(); menu.AppendSeparator();
#endif #endif
menu.Append(IDM_RENAMESYMBOL, wxString::FromAscii("Rename &symbol")); menu.Append(IDM_RENAMESYMBOL, wxString::FromAscii("Rename &symbol"))->Enable(isSymbol);
menu.AppendSeparator(); menu.AppendSeparator();
menu.Append(IDM_RUNTOHERE, _T("&Run To Here")); menu.Append(IDM_RUNTOHERE, _T("&Run To Here"));
menu.Append(IDM_JITRESULTS, wxString::FromAscii("PPC vs X86")); menu.Append(IDM_JITRESULTS, wxString::FromAscii("PPC vs X86"));
@ -373,8 +406,6 @@ void CCodeView::OnPaint(wxPaintEvent& event)
found = true; found = true;
} }
} }
if (!found) if (!found)
{ {
mojs = 0; mojs = 0;

View File

@ -24,11 +24,12 @@
#include <wx/wx.h> #include <wx/wx.h>
DECLARE_EVENT_TYPE(wxEVT_CODEVIEW_CHANGE, -1);
class CCodeView class CCodeView
: public wxControl : public wxControl
{ {
public: public:
CCodeView(DebugInterface* debuginterface, wxWindow* parent, wxWindowID Id = -1, const wxSize& Size = wxDefaultSize); CCodeView(DebugInterface* debuginterface, wxWindow* parent, wxWindowID Id = -1, const wxSize& Size = wxDefaultSize);
wxSize DoGetBestSize() const; wxSize DoGetBestSize() const;
void OnPaint(wxPaintEvent& event); void OnPaint(wxPaintEvent& event);
@ -39,21 +40,21 @@ class CCodeView
void OnMouseUpR(wxMouseEvent& event); void OnMouseUpR(wxMouseEvent& event);
void OnPopupMenu(wxCommandEvent& event); void OnPopupMenu(wxCommandEvent& event);
u32 GetSelection() {return(selection);} u32 GetSelection() {return(selection);}
void Center(u32 addr) void Center(u32 addr)
{ {
curAddress = addr; curAddress = addr;
selection = addr;
redraw(); redraw();
} }
private: private:
void RaiseEvent();
int YToAddress(int y); int YToAddress(int y);
u32 AddrToBranch(u32 addr);
void redraw() {Refresh();} void redraw() {Refresh();}

View File

@ -67,6 +67,8 @@ static const long TOOLBAR_STYLE = wxTB_FLAT | wxTB_DOCKABLE | wxTB_TEXT;
BEGIN_EVENT_TABLE(CCodeWindow, wxFrame) BEGIN_EVENT_TABLE(CCodeWindow, wxFrame)
EVT_LISTBOX(IDM_SYMBOLLIST, CCodeWindow::OnSymbolListChange) EVT_LISTBOX(IDM_SYMBOLLIST, CCodeWindow::OnSymbolListChange)
EVT_LISTBOX(IDM_CALLSTACKLIST, CCodeWindow::OnCallstackListChange) 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_HOST_COMMAND(wxID_ANY, CCodeWindow::OnHostMessage)
EVT_MENU(IDM_LOGWINDOW, CCodeWindow::OnToggleLogWindow) EVT_MENU(IDM_LOGWINDOW, CCodeWindow::OnToggleLogWindow)
EVT_MENU(IDM_REGISTERWINDOW, CCodeWindow::OnToggleRegisterWindow) EVT_MENU(IDM_REGISTERWINDOW, CCodeWindow::OnToggleRegisterWindow)
@ -90,6 +92,8 @@ BEGIN_EVENT_TABLE(CCodeWindow, wxFrame)
EVT_MENU(IDM_SETPC, CCodeWindow::OnCodeStep) EVT_MENU(IDM_SETPC, CCodeWindow::OnCodeStep)
EVT_MENU(IDM_GOTOPC, CCodeWindow::OnCodeStep) EVT_MENU(IDM_GOTOPC, CCodeWindow::OnCodeStep)
EVT_TEXT(IDM_ADDRBOX, CCodeWindow::OnAddrBoxChange) EVT_TEXT(IDM_ADDRBOX, CCodeWindow::OnAddrBoxChange)
EVT_COMMAND(IDM_CODEVIEW, wxEVT_CODEVIEW_CHANGE, CCodeWindow::OnCodeViewChange)
END_EVENT_TABLE() END_EVENT_TABLE()
#define wxGetBitmapFromMemory(name) _wxGetBitmapFromMemory(name, sizeof(name)) #define wxGetBitmapFromMemory(name) _wxGetBitmapFromMemory(name, sizeof(name))
@ -175,12 +179,14 @@ void CCodeWindow::CreateGUIControls(const SCoreStartupParameter& _LocalCoreStart
DebugInterface* di = new PPCDebugInterface(); 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(sizerLeft, 2, wxEXPAND);
sizerBig->Add(codeview, 5, wxEXPAND); sizerBig->Add(codeview, 5, wxEXPAND);
sizerLeft->Add(callstack = new wxListBox(this, IDM_CALLSTACKLIST, wxDefaultPosition, wxSize(90, 100)), 0, 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(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); SetSizer(sizerBig);
@ -283,11 +289,6 @@ bool CCodeWindow::UseDualCore()
} }
void CCodeWindow::JumpToAddress(u32 _Address)
{
codeview->Center(_Address);
}
void CCodeWindow::OnJitMenu(wxCommandEvent& event) void CCodeWindow::OnJitMenu(wxCommandEvent& event)
{ {
switch (event.GetId()) switch (event.GetId())
@ -378,7 +379,7 @@ void CCodeWindow::OnCodeStep(wxCommandEvent& event)
case IDM_DEBUG_GO: case IDM_DEBUG_GO:
{ {
// [F|RES] prolly we should disable the other buttons in go mode too ... // [F|RES] prolly we should disable the other buttons in go mode too ...
codeview->Center(PC); JumpToAddress(PC);
if (CCPU::IsStepping()) if (CCPU::IsStepping())
{ {
@ -414,7 +415,7 @@ void CCodeWindow::OnCodeStep(wxCommandEvent& event)
break; break;
case IDM_GOTOPC: case IDM_GOTOPC:
codeview->Center(PC); JumpToAddress(PC);
break; 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) void CCodeWindow::OnAddrBoxChange(wxCommandEvent& event)
{ {
wxTextCtrl* pAddrCtrl = (wxTextCtrl*)GetToolBar()->FindControl(IDM_ADDRBOX); wxTextCtrl* pAddrCtrl = (wxTextCtrl*)GetToolBar()->FindControl(IDM_ADDRBOX);
wxString txt = pAddrCtrl->GetValue(); wxString txt = pAddrCtrl->GetValue();
if (txt.size() == 8) std::string text(txt.c_str());
text = StripSpaces(text);
if (text.size() == 8)
{ {
u32 addr; u32 addr;
sscanf(txt.mb_str(), "%08x", &addr); sscanf(text.c_str(), "%08x", &addr);
codeview->Center(addr); JumpToAddress(addr);
} }
event.Skip(1); 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() void CCodeWindow::Update()
{ {
@ -465,9 +530,9 @@ void CCodeWindow::Update()
void CCodeWindow::NotifyMapLoaded() void CCodeWindow::NotifyMapLoaded()
{ {
g_symbolDB.FillInCallers();
symbols->Show(false); // hide it for faster filling symbols->Show(false); // hide it for faster filling
symbols->Clear(); symbols->Clear();
for (SymbolDB::XFuncMap::iterator iter = g_symbolDB.GetIterator(); iter != g_symbolDB.End(); iter++) for (SymbolDB::XFuncMap::iterator iter = g_symbolDB.GetIterator(); iter != g_symbolDB.End(); iter++)
{ {
int idx = symbols->Append(wxString::FromAscii(iter->second.name.c_str())); int idx = symbols->Append(wxString::FromAscii(iter->second.name.c_str()));
@ -519,7 +584,7 @@ void CCodeWindow::OnSymbolListChange(wxCommandEvent& event)
if (pSymbol != NULL) 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) void CCodeWindow::OnToggleLogWindow(wxCommandEvent& event)
{ {
if (IsLoggingActivated()) if (IsLoggingActivated())
@ -774,7 +827,7 @@ void CCodeWindow::SingleCPUStep()
// sync_event.Wait(); // sync_event.Wait();
wxThread::Sleep(20); wxThread::Sleep(20);
// need a short wait here // need a short wait here
codeview->Center(PC); JumpToAddress(PC);
Update(); Update();
Host_UpdateLogDisplay(); Host_UpdateLogDisplay();
} }

View File

@ -55,6 +55,7 @@ class CCodeWindow
void Update(); void Update();
void NotifyMapLoaded(); void NotifyMapLoaded();
bool UseInterpreter(); bool UseInterpreter();
bool UseDualCore(); bool UseDualCore();
void JumpToAddress(u32 _Address); void JumpToAddress(u32 _Address);
@ -64,6 +65,7 @@ class CCodeWindow
enum enum
{ {
ID_TOOLBAR = 500, ID_TOOLBAR = 500,
IDM_CODEVIEW,
IDM_DEBUG_GO, IDM_DEBUG_GO,
IDM_STEP, IDM_STEP,
IDM_STEPOVER, IDM_STEPOVER,
@ -72,6 +74,8 @@ class CCodeWindow
IDM_GOTOPC, IDM_GOTOPC,
IDM_ADDRBOX, IDM_ADDRBOX,
IDM_CALLSTACKLIST, IDM_CALLSTACKLIST,
IDM_CALLERSLIST,
IDM_CALLSLIST,
IDM_SYMBOLLIST, IDM_SYMBOLLIST,
IDM_INTERPRETER, IDM_INTERPRETER,
IDM_DUALCORE, IDM_DUALCORE,
@ -112,6 +116,8 @@ class CCodeWindow
CCodeView* codeview; CCodeView* codeview;
wxListBox* callstack; wxListBox* callstack;
wxListBox* symbols; wxListBox* symbols;
wxListBox* callers;
wxListBox* calls;
Common::Event sync_event; Common::Event sync_event;
wxBitmap m_Bitmaps[Bitmaps_max]; wxBitmap m_Bitmaps[Bitmaps_max];
@ -121,7 +127,10 @@ class CCodeWindow
void OnSymbolListChange(wxCommandEvent& event); void OnSymbolListChange(wxCommandEvent& event);
void OnSymbolListContextMenu(wxContextMenuEvent& event); void OnSymbolListContextMenu(wxContextMenuEvent& event);
void OnCallstackListChange(wxCommandEvent& event); void OnCallstackListChange(wxCommandEvent& event);
void OnCallersListChange(wxCommandEvent& event);
void OnCallsListChange(wxCommandEvent& event);
void OnCodeStep(wxCommandEvent& event); void OnCodeStep(wxCommandEvent& event);
void OnCodeViewChange(wxCommandEvent &event);
void SingleCPUStep(); void SingleCPUStep();
@ -138,6 +147,7 @@ class CCodeWindow
void CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParameter); void CreateMenu(const SCoreStartupParameter& _LocalCoreStartupParameter);
void UpdateButtonStates(); void UpdateButtonStates();
void UpdateLists();
void RecreateToolbar(); void RecreateToolbar();
void PopulateToolbar(wxToolBar* toolBar); void PopulateToolbar(wxToolBar* toolBar);