Added the return address information in the call stack
[clinton/Virtual-Jaguar-Rx.git] / src / debugger / heapallocatorbrowser.cpp
CommitLineData
0203b5fd 1//\r
570dad92 2// heapallocatorbrowser.cpp: Memory heap allocation\r
0203b5fd
JPM
3//\r
4// by Jean-Paul Mari\r
5//\r
6// JPM = Jean-Paul Mari <djipi.mari@gmail.com>\r
7//\r
8// Who When What\r
9// --- ---------- -----------------------------------------------------------\r
10// JPM 01/08/2017 Created this file\r
5d765b04
JPM
11// JPM 09/05/2018 Support of the DRAM size limit option\r
12// JPM 09/05/2018 Use definitions for error instead of hard values\r
13// JPM 09/05/2018 Detect if heap allocation shares space with SP (Stack)\r
2b91c435
JPM
14// JPM 09/06/2018 Added a status bar and better status report\r
15// JPM 09/07/2018 Set information values in a tab\r
0203b5fd
JPM
16//\r
17\r
18// STILL TO DO:\r
2b91c435
JPM
19// To have filters\r
20// To set the information display at the right\r
21// Feature to list the pointer(s) in the code using the allocation\r
0203b5fd
JPM
22//\r
23\r
2b91c435 24\r
5d765b04 25#include "settings.h"\r
0203b5fd
JPM
26#include "debugger/heapallocatorbrowser.h"\r
27#include "memory.h"\r
28#include "debugger/DBGManager.h"\r
29#include "m68000/m68kinterface.h"\r
30\r
31\r
2b91c435 32// \r
0203b5fd 33HeapAllocatorBrowserWindow::HeapAllocatorBrowserWindow(QWidget * parent/*= 0*/) : QWidget(parent, Qt::Dialog),\r
2b91c435
JPM
34layout(new QVBoxLayout),\r
35#ifdef HA_LAYOUTTEXTS\r
36text(new QTextBrowser),\r
37#else\r
38TableView(new QTableView),\r
39model(new QStandardItemModel),\r
40proxyModel(new QSortFilterProxyModel),\r
41#endif\r
42statusbar(new QStatusBar),\r
0203b5fd 43Adr(0)\r
0203b5fd
JPM
44{\r
45 setWindowTitle(tr("Heap Allocation"));\r
46\r
2b91c435 47 // Set the font\r
0203b5fd 48 QFont fixedFont("Lucida Console", 8, QFont::Normal);\r
0203b5fd 49 fixedFont.setStyleHint(QFont::TypeWriter);\r
0203b5fd 50\r
2b91c435
JPM
51#ifdef HA_LAYOUTTEXTS\r
52 // Set original layout\r
53 text->setFont(fixedFont);\r
0203b5fd 54 layout->addWidget(text);\r
2b91c435
JPM
55#else\r
56 // Set the new layout with proper identation and readibility\r
57 model->setColumnCount(3);\r
58 model->setHeaderData(0, Qt::Horizontal, QObject::tr("Pointer"));\r
59 model->setHeaderData(1, Qt::Horizontal, QObject::tr("Size"));\r
60 model->setHeaderData(2, Qt::Horizontal, QObject::tr("Use"));\r
61 // Information table\r
62 TableView->setModel(model);\r
63 TableView->setEditTriggers(QAbstractItemView::NoEditTriggers);\r
64 TableView->setShowGrid(0);\r
65 TableView->setFont(fixedFont);\r
66 TableView->verticalHeader()->setDefaultSectionSize(TableView->verticalHeader()->minimumSectionSize());\r
67 TableView->verticalHeader()->setDefaultAlignment(Qt::AlignRight);\r
68 layout->addWidget(TableView);\r
69 // Set filter\r
70 proxyModel->setSourceModel(model);\r
71 QRegExp regExp("*", Qt::CaseInsensitive, QRegExp::Wildcard);\r
72 proxyModel->setFilterRegExp(regExp);\r
73#endif\r
74\r
75 // Status bar\r
76 layout->addWidget(statusbar);\r
77 setLayout(layout);\r
0203b5fd
JPM
78}\r
79\r
80\r
81//\r
82HeapAllocatorBrowserWindow::~HeapAllocatorBrowserWindow(void)\r
83{\r
0203b5fd
JPM
84}\r
85\r
86\r
87//\r
88void HeapAllocatorBrowserWindow::RefreshContents(void)\r
89{\r
2b91c435
JPM
90#ifdef HA_LAYOUTTEXTS\r
91 char string[1024] = { 0 };\r
0203b5fd 92 QString HA;\r
2b91c435
JPM
93#endif\r
94 char msg[1024];\r
95 QString MSG;\r
96 size_t Adr68K, Adr68KHigh;\r
5d765b04 97 size_t Error = HA_NOERROR;\r
2b91c435 98 size_t NbBlocks, TotalBytesUsed;\r
0203b5fd
JPM
99 HeapAllocation HeapAllocation;\r
100\r
101 if (isVisible())\r
102 {\r
103 if (Adr68K = Adr)\r
104 {\r
2b91c435
JPM
105 Adr68KHigh = TotalBytesUsed = NbBlocks = 0;\r
106#ifndef HA_LAYOUTTEXTS\r
107 model->setRowCount(0);\r
108#endif\r
0203b5fd
JPM
109 do\r
110 {\r
5d765b04 111 if ((Adr68K >= 0x4000) && (Adr68K < vjs.DRAM_size))\r
0203b5fd 112 {\r
5d765b04 113 if (Adr68K < m68k_get_reg(NULL, M68K_REG_SP))\r
0203b5fd 114 {\r
5d765b04
JPM
115 memcpy(&HeapAllocation, &jaguarMainRAM[Adr68K], sizeof(HeapAllocation));\r
116\r
117 if (HeapAllocation.size = ((HeapAllocation.size & 0xff) << 24) + ((HeapAllocation.size & 0xff00) << 8) + ((HeapAllocation.size & 0xff0000) >> 8) + ((HeapAllocation.size & 0xff000000) >> 24))\r
0203b5fd 118 {\r
5d765b04 119 if (HeapAllocation.size <= (vjs.DRAM_size - 0x4000))\r
0203b5fd 120 {\r
5d765b04 121 if ((HeapAllocation.used = ((HeapAllocation.used & 0xff) << 8) + ((HeapAllocation.used & 0xff00) >> 8)) <= 1)\r
0203b5fd 122 {\r
5d765b04
JPM
123 HeapAllocation.nextalloc = ((HeapAllocation.nextalloc & 0xff) << 24) + ((HeapAllocation.nextalloc & 0xff00) << 8) + ((HeapAllocation.nextalloc & 0xff0000) >> 8) + ((HeapAllocation.nextalloc & 0xff000000) >> 24);\r
124\r
125 if ((HeapAllocation.nextalloc >= 0x4000) && (HeapAllocation.nextalloc < vjs.DRAM_size))\r
126 {\r
2b91c435
JPM
127#ifdef HA_LAYOUTTEXTS\r
128 if (NbBlocks++)\r
129 {\r
130 HA += QString("<br>");\r
131 }\r
132 sprintf(string, "0x%06x | 0x%0x (%zi) | %s | 0x%06x", Adr68K, HeapAllocation.size - sizeof(HeapAllocation), HeapAllocation.size - sizeof(HeapAllocation), HeapAllocation.used ? "Allocated" : "Free", HeapAllocation.nextalloc);\r
133 HA += QString(string);\r
134#else\r
135 model->insertRow(NbBlocks);\r
136 model->setItem(NbBlocks, 0, new QStandardItem(QString("0x%1").arg(Adr68K, 6, 16, QChar('0'))));\r
137 model->setItem(NbBlocks, 1, new QStandardItem(QString("%1").arg((HeapAllocation.size - sizeof(HeapAllocation)))));\r
138 model->setItem(NbBlocks++, 2, new QStandardItem(QString("%1").arg(HeapAllocation.used ? "Allocated" : "Free")));\r
139#endif\r
140 TotalBytesUsed += HeapAllocation.size;\r
141\r
142 if ((Adr68K = HeapAllocation.nextalloc) > Adr68KHigh)\r
143 {\r
144 Adr68KHigh = Adr68K;\r
145 }\r
5d765b04
JPM
146 }\r
147 else\r
148 {\r
2b91c435 149 sprintf(msg, "Unable to determine the next memory allocation");\r
5d765b04
JPM
150 Error = HA_UNABLENEXTMEMORYALLOC;\r
151 }\r
0203b5fd
JPM
152 }\r
153 else\r
154 {\r
2b91c435 155 sprintf(msg, "Unable to determine if the allocated memory is used or not");\r
5d765b04 156 Error = HA_UNABLEALLOCATEMEMORYUSAGE;\r
0203b5fd
JPM
157 }\r
158 }\r
159 else\r
160 {\r
2b91c435 161 sprintf(msg, "Memory bloc size has a problem");\r
5d765b04 162 Error = HA_MEMORYBLOCKSIZEPROBLEM;\r
0203b5fd
JPM
163 }\r
164 }\r
165 else\r
166 {\r
2b91c435 167 sprintf(msg, "%i blocks | %i bytes in blocks | %i contiguous bytes free", NbBlocks, TotalBytesUsed, (m68k_get_reg(NULL, M68K_REG_SP) - Adr68KHigh));\r
0203b5fd
JPM
168 }\r
169 }\r
170 else\r
171 {\r
2b91c435 172 sprintf(msg, "Memory allocations and Stack have reached the same space");\r
5d765b04 173 Error = HA_HAANDSPSHARESPACE;\r
0203b5fd
JPM
174 }\r
175 }\r
176 else\r
177 {\r
2b91c435 178 sprintf(msg, "Memory allocations may have a problem");\r
5d765b04 179 Error = HA_MEMORYALLOCATIONPROBLEM;\r
0203b5fd 180 }\r
5d765b04
JPM
181 }\r
182 while (HeapAllocation.size && !Error);\r
2b91c435
JPM
183\r
184 MSG += QString(msg);\r
0203b5fd
JPM
185 }\r
186 else\r
187 {\r
188 if (Adr = DBGManager_GetAdrFromSymbolName((char *)"__HeapBase"))\r
189 {\r
190 if (Adr68K = DBGManager_GetGlobalVariableAdrFromName((char *)"alloc"))\r
191 {\r
192 if (!(Adr68K = (jaguarMainRAM[Adr68K] << 24) + (jaguarMainRAM[Adr68K + 1] << 16) + (jaguarMainRAM[Adr68K + 2] << 8) + (jaguarMainRAM[Adr68K + 3])) || ((Adr68K < 0x4000) || (Adr68K >= 0x200000)))\r
193 {\r
2b91c435
JPM
194 sprintf(msg, "Memory allocator not yet initialised");\r
195 Error = HA_MEMORYALLOCATORNOTINITIALIZED;\r
0203b5fd
JPM
196 Adr = 0;\r
197 }\r
198 else\r
199 {\r
200 return RefreshContents();\r
0203b5fd
JPM
201 }\r
202 }\r
203 else\r
204 {\r
2b91c435
JPM
205 sprintf(msg, "Memory allocator is not compatible");\r
206 Error = HA_MEMORYALLOCATORNOTCOMPATIBLE;\r
0203b5fd
JPM
207 Adr = 0;\r
208 }\r
209 }\r
210 else\r
211 {\r
2b91c435
JPM
212 sprintf(msg, "Memory allocator doesn't exist");\r
213 Error = HA_MEMORYALLOCATORNOTEXIST;\r
0203b5fd 214 }\r
2b91c435
JPM
215#ifdef HA_LAYOUTTEXTS\r
216 HA += QString("");\r
217#else\r
218 model->setRowCount(0);\r
219#endif\r
220 MSG += QString(msg);\r
221 }\r
0203b5fd 222\r
2b91c435
JPM
223 // Display status bar\r
224 if (Error)\r
225 {\r
226 if ((Error & HA_WARNING))\r
227 {\r
228 statusbar->setStyleSheet("background-color: lightyellow; font: bold");\r
229 }\r
230 else\r
231 {\r
232 statusbar->setStyleSheet("background-color: tomato; font: bold");\r
233 }\r
234 }\r
235 else\r
236 {\r
237 statusbar->setStyleSheet("background-color: lightgreen; font: bold");\r
0203b5fd 238 }\r
2b91c435 239 statusbar->showMessage(MSG);\r
0203b5fd 240\r
2b91c435
JPM
241#ifdef HA_LAYOUTTEXTS\r
242 // Display values\r
0203b5fd
JPM
243 text->clear();\r
244 text->setText(HA);\r
2b91c435 245#endif\r
0203b5fd
JPM
246 }\r
247}\r
248\r
249\r
a2dfb8e5
JPM
250// \r
251void HeapAllocatorBrowserWindow::Reset(void)\r
252{\r
253 size_t Adr68K;\r
254\r
255 if (DBGManager_GetAdrFromSymbolName((char *)"__HeapBase"))\r
256 {\r
257 if (Adr68K = DBGManager_GetGlobalVariableAdrFromName((char *)"alloc"))\r
258 {\r
259 jaguarMainRAM[Adr68K] = jaguarMainRAM[Adr68K + 1] = jaguarMainRAM[Adr68K + 2] = jaguarMainRAM[Adr68K + 3] = 0;\r
260 Adr = 0;\r
261 }\r
262 }\r
263}\r
264\r
265\r
266// \r
0203b5fd
JPM
267void HeapAllocatorBrowserWindow::keyPressEvent(QKeyEvent * e)\r
268{\r
269 if (e->key() == Qt::Key_Escape)\r
a2dfb8e5 270 {\r
0203b5fd 271 hide();\r
a2dfb8e5 272 }\r
0203b5fd 273}\r
0203b5fd 274\r