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 
24 class DebuggerIO;
25 
27 {
28 }
29 
31 {
32 }
33 
35  const HugeStaticString &input, HugeStaticString &output)
36 {
37  output = "[ {0,1,2,3} {address,trigger,size,enable} [{parameter}] ]";
38 }
39 
41  const HugeStaticString &input, HugeStaticString &output,
42  InterruptState &state, DebuggerIO *pScreen)
43 {
44  // Did we get any input?
45  if (input == "breakpoint")
46  {
47  // Print out the current breakpoint status.
48  output = "Current breakpoint status:\n";
49  for (size_t i = 0; i < Processor::getDebugBreakpointCount(); i++)
50  {
51  DebugFlags::FaultType nFt;
52  size_t nLen;
53  bool bEnabled;
54  uintptr_t nAddress =
55  Processor::getDebugBreakpoint(i, nFt, nLen, bEnabled);
56 
57  const char *pFaultType = 0;
58  switch (nFt)
59  {
60  case DebugFlags::InstructionFetch:
61  pFaultType = "InstructionFetch";
62  break;
63  case DebugFlags::DataWrite:
64  pFaultType = "DataWrite";
65  break;
66  case DebugFlags::IOReadWrite:
67  pFaultType = "IOReadWrite";
68  break;
69  case DebugFlags::DataReadWrite:
70  pFaultType = "DataReadWrite";
71  break;
72  }
73 
74  const char *pEnabled = "disabled";
75  if (bEnabled)
76  pEnabled = "enabled";
77  output += i;
78  output += ": 0x";
79  output.append(nAddress, 16, sizeof(uintptr_t) * 2, '0');
80  output += " \t";
81  output.append(pFaultType);
82  output += " \t";
83  output.append(nLen);
84  output += " \t";
85  output.append(pEnabled);
86  output += "\n";
87  }
88  }
89  else
90  {
91  LargeStaticString inputCopy(input);
92  // We expect a number.
93  int32_t nBp = input.intValue();
94  if (nBp < 0 ||
95  nBp >= static_cast<int32_t>(Processor::getDebugBreakpointCount()))
96  {
97  output = "Invalid breakpoint number.\n";
98  return true;
99  }
100  // We expect a word - find the next space.
101  bool bSpaceFound = false;
102  for (size_t i = 0; i < inputCopy.length(); i++)
103  if (inputCopy[i] == ' ')
104  {
105  inputCopy.stripFirst(i + 1);
106  bSpaceFound = true;
107  break;
108  }
109 
110  if (!bSpaceFound)
111  {
112  output = "Command not recognised\n";
113  return true;
114  }
115 
116  NormalStaticString command;
117  // Find another space - end of command.
118  bSpaceFound = false;
119  for (size_t i = 0; i < inputCopy.length(); i++)
120  if (inputCopy[i] == ' ')
121  {
122  command = inputCopy.left(i);
123  inputCopy.stripFirst(i + 1);
124  bSpaceFound = true;
125  break;
126  }
127 
128  if (!bSpaceFound)
129  {
130  output = "Command not recognised\n";
131  return true;
132  }
133 
134  NormalStaticString argument;
135  // Find another space - end of argument.
136  bSpaceFound = false;
137  for (size_t i = 0; i < inputCopy.length(); i++)
138  if (inputCopy[i] == ' ')
139  {
140  argument = inputCopy.left(i);
141  bSpaceFound = true;
142  break;
143  }
144  if (!bSpaceFound)
145  argument = inputCopy;
146 
147  if (argument.length() == 0)
148  {
149  output = "Parameter had zero length!\n";
150  return true;
151  }
152 
153  // Get the current breakpoint status.
154  DebugFlags::FaultType nFaultType;
155  size_t nLength;
156  bool bEnabled;
157  uintptr_t address =
158  Processor::getDebugBreakpoint(nBp, nFaultType, nLength, bEnabled);
159 
160  if (command == "address")
161  {
162  address = argument.intValue();
163  Processor::enableDebugBreakpoint(nBp, address, nFaultType, nLength);
164  }
165  else if (command == "trigger")
166  {
167  }
168  else if (command == "enabled")
169  {
170  if (argument == "yes" || argument == "true")
171  {
173  nBp, address, nFaultType, nLength);
174  }
175  else
176  {
178  }
179  }
180  else
181  {
182  output = "Unrecognised command.\n";
183  return true;
184  }
185  }
186 
187  return true;
188 }
static uintptr_t getDebugBreakpoint(size_t nBpNumber, DebugFlags::FaultType &nFaultType, size_t &nLength, bool &bEnabled)
void autocomplete(const HugeStaticString &input, HugeStaticString &output)
static void enableDebugBreakpoint(size_t nBpNumber, uintptr_t nLinearAddress, DebugFlags::FaultType nFaultType, size_t nLength)
static void disableDebugBreakpoint(size_t nBpNumber)
static size_t getDebugBreakpointCount()
bool execute(const HugeStaticString &input, HugeStaticString &output, InterruptState &state, DebuggerIO *screen)