20#include "pedigree/kernel/debugger/DebuggerIO.h"
21#include "pedigree/kernel/debugger/commands/TraceCommand.h"
22#include "pedigree/kernel/linker/KernelElf.h"
23#include "pedigree/kernel/processor/Disassembler.h"
24#include "pedigree/kernel/processor/Processor.h"
25#include "pedigree/kernel/processor/state.h"
26#include "pedigree/kernel/utilities/demangle.h"
34void TraceCommand::setInterface(
int nInterface) {
35 m_nInterface = nInterface;
42 pScreen->disableCli();
46 int nCols = pScreen->
getWidth() - 25;
48 int nLines = ((pScreen->getHeight() - 2) * 3) / 4;
51 disassembly.move(0, 1);
52 disassembly.resize(nCols, nLines);
53 disassembly.setScrollKeys(
'o',
'p');
56 registers.move(nCols + 1, 1);
57 registers.resize(24, nLines);
58 registers.setScrollKeys(
'j',
'k');
61 stacktrace.move(0, nLines + 2);
62 stacktrace.resize(pScreen->
getWidth(), pScreen->getHeight() - nLines - 3);
63 stacktrace.setScrollKeys(
'n',
'm');
65 size_t nInstruction = 0;
68 uintptr_t nIp = state.getInstructionPointer();
69 uintptr_t nSymStart = 0;
80 while (nInstruction < disassembly.getLineCount()) {
85 if (nLocation == state.getInstructionPointer())
89 disassembly.centreOn(nInstruction);
91 pScreen->disableRefreshes();
92 drawBackground(nCols, nLines, pScreen);
93 registers.refresh(pScreen);
94 disassembly.refresh(pScreen);
95 stacktrace.refresh(pScreen);
99 bool bContinue =
true;
102 while ((c = pScreen->
getChar()) == 0)
110 }
else if (c ==
'o') {
111 disassembly.scroll(-1);
112 disassembly.refresh(pScreen);
113 }
else if (c ==
'p') {
114 disassembly.scroll(1);
115 disassembly.refresh(pScreen);
116 }
else if (c ==
'j') {
117 registers.scroll(-1);
118 registers.refresh(pScreen);
119 }
else if (c ==
'k') {
121 registers.refresh(pScreen);
122 }
else if (c ==
'n') {
123 stacktrace.scroll(-1);
124 stacktrace.refresh(pScreen);
125 }
else if (c ==
'm') {
126 stacktrace.scroll(1);
127 stacktrace.refresh(pScreen);
136void TraceCommand::drawBackground(
size_t nCols,
size_t nLines,
DebuggerIO* pScreen) {
144 DebuggerIO::White, DebuggerIO::Green);
146 pScreen->
drawString(
"Pedigree debugger - Execution Tracer", 0, 0, DebuggerIO::White,
149 pScreen->
drawString(
"s: Step. c: Continue. q: Quit. ?: Current instruction. ?: Breakpoint.",
150 pScreen->getHeight() - 1, 0, DebuggerIO::White, DebuggerIO::Green);
151 pScreen->
drawString(
"s", pScreen->getHeight() - 1, 0, DebuggerIO::Yellow, DebuggerIO::Green);
152 pScreen->
drawString(
"c", pScreen->getHeight() - 1, 9, DebuggerIO::Yellow, DebuggerIO::Green);
153 pScreen->
drawString(
"q", pScreen->getHeight() - 1, 22, DebuggerIO::Yellow, DebuggerIO::Green);
154 pScreen->
drawString(
" ", pScreen->getHeight() - 1, 31, DebuggerIO::Yellow, DebuggerIO::Blue);
155 pScreen->
drawString(
" ", pScreen->getHeight() - 1, 55, DebuggerIO::Yellow, DebuggerIO::Red);
159 pScreen->drawVerticalLine(
'|', nCols, 1, nLines, DebuggerIO::DarkGrey, DebuggerIO::Black);
162TraceCommand::Disassembly::Disassembly(InterruptState& state)
163 : m_nInstructions(0),
164 m_nFirstInstruction(0),
166 m_LastLine(0xFFFFFFFF),
167 m_LastInstructionLocation(0) {
169 m_nIp = state.getInstructionPointer();
170 uintptr_t nSymStart = 0;
179 m_nFirstInstruction = nSymStart;
180 uintptr_t nLocation = 0;
188 if (nSym == nLocation && nSym != nSymStart)
194const char* TraceCommand::Disassembly::getLine1(
size_t index,
DebuggerIO::Colour& colour,
199 colour = DebuggerIO::Yellow;
209 size_t nInstruction = 0;
216 uintptr_t nLocation = 0;
220 disassembler.
setLocation(m_LastInstructionLocation);
230 while (nInstruction <= index) {
238 m_LastInstructionLocation = nLocation;
242 if (nLocation == m_nIp)
243 bgColour = DebuggerIO::Blue;
246 colour = DebuggerIO::DarkGrey;
250 sym.append(nLocation, 16,
sizeof(uintptr_t) * 2,
'0');
255const char* TraceCommand::Disassembly::getLine2(
size_t index,
size_t& colOffset,
265 size_t nInstruction = 0;
272 uintptr_t nLocation = 0;
274 if (index == m_LastLine) {
275 disassembler.
setLocation(m_LastInstructionLocation);
276 nLocation = m_LastInstructionLocation;
280 while (nInstruction <= index) {
290 if (nLocation == m_nIp)
291 bgColour = DebuggerIO::Blue;
294 colour = DebuggerIO::White;
297 colOffset =
sizeof(uintptr_t) * 2 + 1;
302 uint32_t nLen = sym.length() + colOffset;
303 while (nLen++ < width())
308size_t TraceCommand::Disassembly::getLineCount() {
309 return m_nInstructions + 1;
312TraceCommand::Registers::Registers(InterruptState& state) : m_State(state) {}
314const char* TraceCommand::Registers::getLine1(
size_t index,
DebuggerIO::Colour& colour,
317 colour = DebuggerIO::Yellow;
321 if (m_State.kernelMode())
327 int nRegister = index - 1;
329 str = m_State.getRegisterName(nRegister);
334const char* TraceCommand::Registers::getLine2(
size_t index,
size_t& colOffset,
342 int nRegister = index - 1;
344 uintptr_t nValue = m_State.getRegister(nRegister);
346 str.append(nValue, 16,
sizeof(uintptr_t) * 2,
'0');
347 colOffset = width() - 2 *
sizeof(uintptr_t) - 2;
352size_t TraceCommand::Registers::getLineCount() {
353 return m_State.getRegisterCount() + 1;
356TraceCommand::Stacktrace::Stacktrace(InterruptState& state) : m_Bt() {
357 m_Bt.performBacktrace(state);
360const char* TraceCommand::Stacktrace::getLine1(
size_t index,
DebuggerIO::Colour& colour,
364 m_Bt.prettyPrint(str, 1, index);
366 str = str.left(str.length() - 1);
370const char* TraceCommand::Stacktrace::getLine2(
size_t index,
size_t& colOffset,
376size_t TraceCommand::Stacktrace::getLineCount() {
377 return m_Bt.numStackFrames();
virtual void enableCli()=0
virtual void enableRefreshes()=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
static KernelElf & instance()
uintptr_t globalLookupSymbol(const char *pName)
static void setSingleStep(bool bEnable, InterruptState &state)
void autocomplete(const HugeStaticString &input, HugeStaticString &output)
bool execute(const HugeStaticString &input, HugeStaticString &output, InterruptState &state, DebuggerIO *screen)
void setLocation(uintptr_t location)
void disassemble(LargeStaticString &text)
void setMode(size_t mode)