summaryrefslogtreecommitdiff
path: root/src/citra_qt/debugger/callstack.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/citra_qt/debugger/callstack.cpp66
1 files changed, 66 insertions, 0 deletions
diff --git a/src/citra_qt/debugger/callstack.cpp b/src/citra_qt/debugger/callstack.cpp
new file mode 100644
index 000000000..f59f2d8c8
--- /dev/null
+++ b/src/citra_qt/debugger/callstack.cpp
@@ -0,0 +1,66 @@
1#include <QStandardItemModel>
2
3#include "callstack.hxx"
4
5#include "core/core.h"
6#include "core/arm/arm_interface.h"
7#include "core/mem_map.h"
8#include "common/symbols.h"
9#include "core/arm/disassembler/arm_disasm.h"
10
11CallstackWidget::CallstackWidget(QWidget* parent): QDockWidget(parent)
12{
13 ui.setupUi(this);
14
15 callstack_model = new QStandardItemModel(this);
16 callstack_model->setColumnCount(4);
17 callstack_model->setHeaderData(0, Qt::Horizontal, "Stack pointer");
18 callstack_model->setHeaderData(2, Qt::Horizontal, "Return address");
19 callstack_model->setHeaderData(1, Qt::Horizontal, "Call address");
20 callstack_model->setHeaderData(3, Qt::Horizontal, "Function");
21 ui.treeView->setModel(callstack_model);
22}
23
24void CallstackWidget::OnCPUStepped()
25{
26 ARM_Disasm* disasm = new ARM_Disasm();
27 ARM_Interface* app_core = Core::g_app_core;
28
29 u32 sp = app_core->GetReg(13); //stack pointer
30 u32 addr, ret_addr, call_addr, func_addr;
31
32 int counter = 0;
33 for (int addr = 0x10000000; addr >= sp; addr -= 4)
34 {
35 ret_addr = Memory::Read32(addr);
36 call_addr = ret_addr - 4; //get call address???
37
38 /* TODO (mattvail) clean me, move to debugger interface */
39 u32 insn = Memory::Read32(call_addr);
40 if (disasm->decode(insn) == OP_BL)
41 {
42 std::string name;
43 // ripped from disasm
44 uint8_t cond = (insn >> 28) & 0xf;
45 uint32_t i_offset = insn & 0xffffff;
46 // Sign-extend the 24-bit offset
47 if ((i_offset >> 23) & 1)
48 i_offset |= 0xff000000;
49
50 // Pre-compute the left-shift and the prefetch offset
51 i_offset <<= 2;
52 i_offset += 8;
53 func_addr = call_addr + i_offset;
54
55 callstack_model->setItem(counter, 0, new QStandardItem(QString("0x%1").arg(addr, 8, 16, QLatin1Char('0'))));
56 callstack_model->setItem(counter, 1, new QStandardItem(QString("0x%1").arg(ret_addr, 8, 16, QLatin1Char('0'))));
57 callstack_model->setItem(counter, 2, new QStandardItem(QString("0x%1").arg(call_addr, 8, 16, QLatin1Char('0'))));
58
59 name = Symbols::HasSymbol(func_addr) ? Symbols::GetSymbol(func_addr).name : "unknown";
60 callstack_model->setItem(counter, 3, new QStandardItem(QString("%1_%2").arg(QString::fromStdString(name))
61 .arg(QString("0x%1").arg(func_addr, 8, 16, QLatin1Char('0')))));
62
63 counter++;
64 }
65 }
66} \ No newline at end of file