20#include "pedigree/kernel/debugger/commands/MemoryInspector.h"
21#include "pedigree/kernel/processor/Processor.h"
22#include "pedigree/kernel/processor/ProcessorInformation.h"
23#include "pedigree/kernel/processor/VirtualAddressSpace.h"
24#include "pedigree/kernel/processor/state.h"
31 output =
"<Address> | <Register name>";
37 if (input ==
"memory")
42 if (!tryGoto(addrString, nAddress, state)) {
43 output =
"Bad address or register.\n";
54 pScreen->disableCli();
58 resize(pScreen->
getWidth(), pScreen->getHeight() - 3);
59 setScrollKeys(
'j',
'k');
66 pScreen->
drawString(
"Pedigree debugger - Memory inspector", 0, 0, DebuggerIO::White,
69 resetStatusLine(pScreen);
71 scrollTo(nAddress / m_nCharsPerLine);
80 while ((c = pScreen->
getChar()) == 0)
89 scroll(
static_cast<ssize_t
>(height()));
91 scroll(-
static_cast<ssize_t
>(height()));
95 doGoto(pScreen, state);
97 doSearch(
true, pScreen, state);
99 doSearch(
false, pScreen, state);
106 pScreen->
drawString(
" ", 1, 0, DebuggerIO::White, DebuggerIO::Black);
113 colour = DebuggerIO::DarkGrey;
114 uintptr_t nLine = index * m_nCharsPerLine;
117 str.append(nLine, 16,
sizeof(uintptr_t) * 2,
'0');
121const char* MemoryInspector::getLine2(
size_t index,
size_t& colOffset,
DebuggerIO::Colour& colour,
123 colOffset =
sizeof(uintptr_t) * 2 + 1;
125 uintptr_t nLine = index * m_nCharsPerLine;
128 colour = DebuggerIO::Red;
129 return "Memory not mapped.";
131 uint8_t* pLine =
reinterpret_cast<uint8_t*
>(nLine);
134 for (
unsigned int i = 0; i < m_nCharsPerLine; i++) {
135 str.append(pLine[i], 16, 2,
'0');
137 if (((i + 1) % 8 == 0) && ((i + 1) < m_nCharsPerLine))
142 for (
unsigned int i = 0; i < m_nCharsPerLine; i++) {
143 if (pLine[i] >= 33 && pLine[i] <= 126)
144 str.append(
static_cast<char>(pLine[i]), 1);
153size_t MemoryInspector::getLineCount() {
159 return 0x2000000000000000;
163void MemoryInspector::resetStatusLine(
DebuggerIO* pScreen) {
169 DebuggerIO::White, DebuggerIO::Green);
174 "backspace: Page up. space: Page down. q: Quit. /,?: Fwd/Rev search. "
176 pScreen->getHeight() - 1, 0, DebuggerIO::White, DebuggerIO::Green);
177 pScreen->
drawString(
"backspace", pScreen->getHeight() - 1, 0, DebuggerIO::Yellow,
179 pScreen->
drawString(
"space", pScreen->getHeight() - 1, 20, DebuggerIO::Yellow, DebuggerIO::Green);
180 pScreen->
drawString(
"q", pScreen->getHeight() - 1, 38, DebuggerIO::Yellow, DebuggerIO::Green);
181 pScreen->
drawString(
"/,?", pScreen->getHeight() - 1, 47, DebuggerIO::Yellow, DebuggerIO::Green);
182 pScreen->
drawString(
"g", pScreen->getHeight() - 1, 68, DebuggerIO::Yellow, DebuggerIO::Green);
185void MemoryInspector::doGoto(
DebuggerIO* pScreen, InterruptState& state) {
191 DebuggerIO::White, DebuggerIO::Black);
193 pScreen->
drawString(
"[Go to address or register value]", pScreen->getHeight() - 2, 0,
194 DebuggerIO::White, DebuggerIO::Black);
196 pScreen->
drawString(str, pScreen->getHeight() - 2, 35, DebuggerIO::White, DebuggerIO::Black);
199 while ((c = pScreen->
getChar()) == 0)
201 if (c ==
'\n' || c ==
'\r')
210 DebuggerIO::White, DebuggerIO::Black);
213 if (!tryGoto(str, nAddress, state)) {
214 pScreen->
drawString(
"Bad address or register.", pScreen->getHeight() - 2, 0, DebuggerIO::Red,
217 scrollTo(nAddress / m_nCharsPerLine);
221void MemoryInspector::doSearch(
bool bForward,
DebuggerIO* pScreen, InterruptState& state) {
228 DebuggerIO::White, DebuggerIO::Black);
231 pScreen->
drawString(
"[Search] ", pScreen->getHeight() - 2, 0, DebuggerIO::White,
234 pScreen->
drawString(
"[Reverse]", pScreen->getHeight() - 2, 0, DebuggerIO::White,
237 pScreen->
drawString(str, pScreen->getHeight() - 2, 10, DebuggerIO::White, DebuggerIO::Black);
240 while ((c = pScreen->
getChar()) == 0)
242 if (c ==
'\n' || c ==
'\r')
251 DebuggerIO::White, DebuggerIO::Black);
253 unsigned int nChars = 0;
262 if (str.length() > 8) {
263 pScreen->
drawString(
"Search string too long (> 8 characters)", pScreen->getHeight() - 2, 0,
264 DebuggerIO::Red, DebuggerIO::Black);
268 nChars = str.length();
269 for (
size_t i = 0; i < str.length(); i++)
273 if (str.left(2) ==
"0x")
275 nChars = str.length() / 2;
277 pScreen->
drawString(
"Hex string too long, 8 bytes max.", pScreen->getHeight() - 2, 0,
278 DebuggerIO::Red, DebuggerIO::Black);
281 for (
size_t i = 0; i < nChars; i++) {
285 mystr += str[i * 2 + 1];
287 int nConverted = mystr.intValue(16);
289 if (nConverted == -1) {
290 pScreen->
drawString(
"Malformed hexadecimal number.", pScreen->getHeight() - 2, 0,
291 DebuggerIO::Red, DebuggerIO::Black);
294 pChars[nChars - i - 1] =
static_cast<uint8_t
>(nConverted);
299 str =
"[Search for ";
301 str =
"[Reverse for ";
302 for (
size_t i = 0; i < nChars; i++) {
303 str.append(pChars[i], 16, 2,
'0');
306 str +=
": over ?(K|M) of memory]";
307 pScreen->
drawString(str, pScreen->getHeight() - 2, 0, DebuggerIO::White, DebuggerIO::Black);
313 DebuggerIO::White, DebuggerIO::Black);
315 pScreen->
drawString(str, pScreen->getHeight() - 2, 0, DebuggerIO::White, DebuggerIO::Black);
317 pScreen->
drawString(str2, pScreen->getHeight() - 2, str.length() + 1, DebuggerIO::White,
321 while ((c = pScreen->
getChar()) == 0)
323 if (c ==
'\n' || c ==
'\r')
333 DebuggerIO::White, DebuggerIO::Black);
335 char suffix = str[0];
336 if (suffix ==
'M' || suffix ==
'K')
338 int num = str2.intValue();
340 pScreen->
drawString(
"Malformed number.", pScreen->getHeight() - 2, 0, DebuggerIO::Red,
344 size_t nRange =
static_cast<size_t>(num);
347 else if (suffix ==
'M')
350 pScreen->
drawString(
"Searching...", pScreen->getHeight() - 2, 0, DebuggerIO::Green,
356bool MemoryInspector::tryGoto(
LargeStaticString& str, uintptr_t& result, InterruptState& state) {
357 for (
size_t i = 0; i < state.getRegisterCount(); i++) {
360 result = state.getRegister(i);
364 uintptr_t n = str.uintptrValue();
virtual void enableCli()=0
virtual void drawString(const char *str, size_t row, size_t col, Colour foreColour, Colour backColour)=0
virtual size_t getWidth()=0
virtual void drawHorizontalLine(char c, size_t row, size_t colStart, size_t colEnd, Colour foreColour, Colour backColour)=0
bool execute(const HugeStaticString &input, HugeStaticString &output, InterruptState &state, DebuggerIO *screen)
void autocomplete(const HugeStaticString &input, HugeStaticString &output)
static ProcessorInformation & information()
StaticString right(int n) const