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