1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
// Copyright 2014 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <QStandardItemModel>
#include "callstack.h"
#include "core/core.h"
#include "core/arm/arm_interface.h"
#include "core/mem_map.h"
#include "common/symbols.h"
#include "core/arm/disassembler/arm_disasm.h"
CallstackWidget::CallstackWidget(QWidget* parent): QDockWidget(parent)
{
ui.setupUi(this);
callstack_model = new QStandardItemModel(this);
callstack_model->setColumnCount(4);
callstack_model->setHeaderData(0, Qt::Horizontal, "Stack Pointer");
callstack_model->setHeaderData(2, Qt::Horizontal, "Return Address");
callstack_model->setHeaderData(1, Qt::Horizontal, "Call Address");
callstack_model->setHeaderData(3, Qt::Horizontal, "Function");
ui.treeView->setModel(callstack_model);
}
void CallstackWidget::OnCPUStepped()
{
ARM_Disasm* disasm = new ARM_Disasm();
ARM_Interface* app_core = Core::g_app_core;
u32 sp = app_core->GetReg(13); //stack pointer
u32 ret_addr, call_addr, func_addr;
int counter = 0;
for (u32 addr = 0x10000000; addr >= sp; addr -= 4)
{
ret_addr = Memory::Read32(addr);
call_addr = ret_addr - 4; //get call address???
/* TODO (mattvail) clean me, move to debugger interface */
u32 insn = Memory::Read32(call_addr);
if (disasm->Decode(insn) == OP_BL)
{
std::string name;
// ripped from disasm
uint8_t cond = (insn >> 28) & 0xf;
uint32_t i_offset = insn & 0xffffff;
// Sign-extend the 24-bit offset
if ((i_offset >> 23) & 1)
i_offset |= 0xff000000;
// Pre-compute the left-shift and the prefetch offset
i_offset <<= 2;
i_offset += 8;
func_addr = call_addr + i_offset;
callstack_model->setItem(counter, 0, new QStandardItem(QString("0x%1").arg(addr, 8, 16, QLatin1Char('0'))));
callstack_model->setItem(counter, 1, new QStandardItem(QString("0x%1").arg(ret_addr, 8, 16, QLatin1Char('0'))));
callstack_model->setItem(counter, 2, new QStandardItem(QString("0x%1").arg(call_addr, 8, 16, QLatin1Char('0'))));
name = Symbols::HasSymbol(func_addr) ? Symbols::GetSymbol(func_addr).name : "unknown";
callstack_model->setItem(counter, 3, new QStandardItem(QString("%1_%2").arg(QString::fromStdString(name))
.arg(QString("0x%1").arg(func_addr, 8, 16, QLatin1Char('0')))));
counter++;
}
}
}
|