The Pedigree Project 0.1
BreakpointCommand.cc
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#include "pedigree/kernel/debugger/commands/BreakpointCommand.h"
21#include "pedigree/kernel/processor/Processor.h"
22#include "pedigree/kernel/processor/types.h"
23
24class DebuggerIO;
25
27
29
31 output = "[ {0,1,2,3} {address,trigger,size,enable} [{parameter}] ]";
32}
33
35 InterruptState& state, DebuggerIO* pScreen) {
36 // Did we get any input?
37 if (input == "breakpoint") {
38 // Print out the current breakpoint status.
39 output = "Current breakpoint status:\n";
40 for (size_t i = 0; i < Processor::getDebugBreakpointCount(); i++) {
41 DebugFlags::FaultType nFt;
42 size_t nLen;
43 bool bEnabled;
44 uintptr_t nAddress = Processor::getDebugBreakpoint(i, nFt, nLen, bEnabled);
45
46 const char* pFaultType = 0;
47 switch (nFt) {
48 case DebugFlags::InstructionFetch:
49 pFaultType = "InstructionFetch";
50 break;
51 case DebugFlags::DataWrite:
52 pFaultType = "DataWrite";
53 break;
54 case DebugFlags::IOReadWrite:
55 pFaultType = "IOReadWrite";
56 break;
57 case DebugFlags::DataReadWrite:
58 pFaultType = "DataReadWrite";
59 break;
60 }
61
62 const char* pEnabled = "disabled";
63 if (bEnabled)
64 pEnabled = "enabled";
65 output += i;
66 output += ": 0x";
67 output.append(nAddress, 16, sizeof(uintptr_t) * 2, '0');
68 output += " \t";
69 output.append(pFaultType);
70 output += " \t";
71 output.append(nLen);
72 output += " \t";
73 output.append(pEnabled);
74 output += "\n";
75 }
76 } else {
77 LargeStaticString inputCopy(input);
78 // We expect a number.
79 int32_t nBp = input.intValue();
80 if (nBp < 0 || nBp >= static_cast<int32_t>(Processor::getDebugBreakpointCount())) {
81 output = "Invalid breakpoint number.\n";
82 return true;
83 }
84 // We expect a word - find the next space.
85 bool bSpaceFound = false;
86 for (size_t i = 0; i < inputCopy.length(); i++)
87 if (inputCopy[i] == ' ') {
88 inputCopy.stripFirst(i + 1);
89 bSpaceFound = true;
90 break;
91 }
92
93 if (!bSpaceFound) {
94 output = "Command not recognised\n";
95 return true;
96 }
97
98 NormalStaticString command;
99 // Find another space - end of command.
100 bSpaceFound = false;
101 for (size_t i = 0; i < inputCopy.length(); i++)
102 if (inputCopy[i] == ' ') {
103 command = inputCopy.left(i);
104 inputCopy.stripFirst(i + 1);
105 bSpaceFound = true;
106 break;
107 }
108
109 if (!bSpaceFound) {
110 output = "Command not recognised\n";
111 return true;
112 }
113
114 NormalStaticString argument;
115 // Find another space - end of argument.
116 bSpaceFound = false;
117 for (size_t i = 0; i < inputCopy.length(); i++)
118 if (inputCopy[i] == ' ') {
119 argument = inputCopy.left(i);
120 bSpaceFound = true;
121 break;
122 }
123 if (!bSpaceFound)
124 argument = inputCopy;
125
126 if (argument.length() == 0) {
127 output = "Parameter had zero length!\n";
128 return true;
129 }
130
131 // Get the current breakpoint status.
132 DebugFlags::FaultType nFaultType;
133 size_t nLength;
134 bool bEnabled;
135 uintptr_t address = Processor::getDebugBreakpoint(nBp, nFaultType, nLength, bEnabled);
136
137 if (command == "address") {
138 address = argument.intValue();
139 Processor::enableDebugBreakpoint(nBp, address, nFaultType, nLength);
140 } else if (command == "trigger") {
141 } else if (command == "enabled") {
142 if (argument == "yes" || argument == "true") {
143 Processor::enableDebugBreakpoint(nBp, address, nFaultType, nLength);
144 } else {
146 }
147 } else {
148 output = "Unrecognised command.\n";
149 return true;
150 }
151 }
152
153 return true;
154}
bool execute(const HugeStaticString &input, HugeStaticString &output, InterruptState &state, DebuggerIO *screen)
void autocomplete(const HugeStaticString &input, HugeStaticString &output)
static uintptr_t getDebugBreakpoint(size_t nBpNumber, DebugFlags::FaultType &nFaultType, size_t &nLength, bool &bEnabled)
static void disableDebugBreakpoint(size_t nBpNumber)
static void enableDebugBreakpoint(size_t nBpNumber, uintptr_t nLinearAddress, DebugFlags::FaultType nFaultType, size_t nLength)
static size_t getDebugBreakpointCount()