1 #include "CallStackWnd.h"
2 #include "string_cast.h"
3 #include "lexical_cast_ex.h"
4 #include "DebugUtils.h"
5 #include "MIPS.h"
6 #include "BiosDebugInfoProvider.h"
7 
8 #include <QVBoxLayout>
9 #include <QLabel>
10 
CCallStackWnd(QWidget * parent,CMIPS * context,CBiosDebugInfoProvider * biosDebugInfoProvider)11 CCallStackWnd::CCallStackWnd(QWidget* parent, CMIPS* context, CBiosDebugInfoProvider* biosDebugInfoProvider)
12     : QListWidget(parent)
13     , m_context(context)
14     , m_biosDebugInfoProvider(biosDebugInfoProvider)
15 {
16 	resize(320, 750);
17 	setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
18 	connect(this, &QListWidget::itemDoubleClicked, this, &CCallStackWnd::listDoubleClick);
19 
20 	Update();
21 }
22 
HandleMachineStateChange()23 void CCallStackWnd::HandleMachineStateChange()
24 {
25 	Update();
26 }
27 
Update()28 void CCallStackWnd::Update()
29 {
30 	uint32 nPC = m_context->m_State.nPC;
31 	uint32 nRA = m_context->m_State.nGPR[CMIPS::RA].nV[0];
32 	uint32 nSP = m_context->m_State.nGPR[CMIPS::SP].nV[0];
33 
34 	clear();
35 
36 	auto callStackItems = CMIPSAnalysis::GetCallStack(m_context, nPC, nSP, nRA);
37 
38 	if(callStackItems.size() == 0)
39 	{
40 		addItem("Call stack unavailable at this state");
41 		return;
42 	}
43 
44 	auto modules = m_biosDebugInfoProvider ? m_biosDebugInfoProvider->GetModulesDebugInfo() : BiosDebugModuleInfoArray();
45 
46 	for(const auto& callStackItem : callStackItems)
47 	{
48 		auto locationString = DebugUtils::PrintAddressLocation(callStackItem, m_context, modules);
49 		addItem(locationString.c_str());
50 	}
51 }
52 
listDoubleClick(QListWidgetItem * item)53 void CCallStackWnd::listDoubleClick(QListWidgetItem* item)
54 {
55 	std::string addressStr = item->text().toStdString();
56 	uint32 nAddress = lexical_cast_hex(addressStr);
57 	if(nAddress != MIPS_INVALID_PC)
58 	{
59 		OnFunctionDblClick(nAddress);
60 	}
61 }
62