BackwardStepCommand.cc Source File

Back to the index.

BackwardStepCommand.cc
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009-2010 Anders Gavare. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *
7  * 1. Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * 3. The name of the author may not be used to endorse or promote products
13  * derived from this software without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
29 #include "GXemul.h"
30 
31 
33  : Command("backward-step", "")
34 {
35 }
36 
37 
39 {
40 }
41 
42 
43 bool BackwardStepCommand::Execute(GXemul& gxemul, const vector<string>& arguments)
44 {
45  StateVariable* stepvar = gxemul.GetRootComponent()->GetVariable("step");
46  uint64_t step = stepvar->ToInteger();
47 
48  if (step == 0) {
49  gxemul.GetUI()->ShowDebugMessage("Cannot go back further; "
50  "already at step 0.\n");
51  return false;
52  }
53 
54  stringstream stepss;
55  stepss << (step - 1);
56 
57  const refcount_ptr<Component> lightClone = gxemul.GetRootComponent()->LightClone();
58 
59  if (!gxemul.GetRootComponent()->SetVariableValue("step", stepss.str())) {
60  gxemul.GetUI()->ShowDebugMessage("Failed to set root.step.\n");
61  return false;
62  }
63 
64  // Indent all debug output with message header "step X -> step X-1: ":
65  stringstream ss;
66  ss << "step " << step << " -> " << (step-1) << ": ";
67  UI::SetIndentationMessageHelper indentationHelper(gxemul.GetUI(), ss.str());
68 
69  // Compare the clone of the component tree before changing the step
70  // with what we have now.
71  stringstream changeMessages;
72  gxemul.GetRootComponent()->DetectChanges(lightClone, changeMessages);
73 
74  string msg = changeMessages.str();
75  if (msg == "")
76  msg = "No state change.\n";
77 
78  gxemul.GetUI()->ShowDebugMessage(msg);
79 
80  return true;
81 }
82 
83 
85 {
86  return "Runs one step of the emulation backwards.";
87 }
88 
89 
91 {
92  return
93  "Runs one step of the emulation backwards. This command does the same as\n"
94  "manually decreasing root.step by 1, except that all state changes are also\n"
95  "displayed, e.g.:\n"
96  "\n"
97  "> backward-step\n"
98  "step 3 -> 2: => cpu0.a1: 0 -> 0x2a\n"
99  " => cpu0.pc: 0xffffffffbfc0004c -> 0xffffffffbfc00048\n"
100  "\n"
101  "This command requires that snapshotting support is enabled (using the\n"
102  "-B command line option).\n";
103 }
104 
105 
106 /*****************************************************************************/
107 
108 
109 #ifdef WITHUNITTESTS
110 
111 static void Test_BackwardStepCommand_AlreadyAtStep0()
112 {
114  vector<string> dummyArguments;
115 
116  GXemul gxemul;
117 
118  UnitTest::Assert("root.step should initially be zero", gxemul.GetStep(), 0);
119 
120  cmd->Execute(gxemul, dummyArguments);
121 
122  UnitTest::Assert("root.step should still be zero", gxemul.GetStep(), 0);
123 }
124 
125 static void Test_BackwardStepCommand_NotWhenSnapshotsAreDisabled()
126 {
128  vector<string> dummyArguments;
129 
130  GXemul gxemul;
131 
132  char filename[] = "test/FileLoader_ELF_MIPS";
133  char *filenames[] = { filename };
134  gxemul.ParseFilenames("testmips", 1, filenames);
135  gxemul.Reset();
136 
137  gxemul.SetSnapshottingEnabled(false);
138 
139  gxemul.GetCommandInterpreter().RunCommand("step 3");
140  gxemul.Execute();
141 
142  UnitTest::Assert("root.step should initially be 3", gxemul.GetStep(), 3);
143 
145  UnitTest::Assert("3: cpu0.pc", cpu->GetVariable("pc")->ToString(), "0xffffffff80010104");
146  UnitTest::Assert("3: cpu0.sp", cpu->GetVariable("sp")->ToString(), "0xffffffffa0007ed0");
147  UnitTest::Assert("3: cpu0.v0", cpu->GetVariable("v0")->ToString(), "0xffffffff88880000");
148  UnitTest::Assert("3: cpu0.v1", cpu->GetVariable("v1")->ToString(), "0xffffffffcccc0000");
149 
150  // This execute should FAIL, because snapshotting is disabled.
151  cmd->Execute(gxemul, dummyArguments);
152  UnitTest::Assert("root.step should still be 3", gxemul.GetStep(), 3);
153 }
154 
155 static void Test_BackwardStepCommand_Basic()
156 {
158  vector<string> dummyArguments;
159 
160  GXemul gxemul;
161 
162  char filename[] = "test/FileLoader_ELF_MIPS";
163  char *filenames[] = { filename };
164  gxemul.ParseFilenames("testmips", 1, filenames);
165  gxemul.Reset();
166 
167  gxemul.SetSnapshottingEnabled(true);
168 
169  gxemul.GetCommandInterpreter().RunCommand("step 3");
170  gxemul.Execute();
171 
172  UnitTest::Assert("root.step should initially be 3", gxemul.GetStep(), 3);
173 
175  UnitTest::Assert("3: cpu0.pc", cpu->GetVariable("pc")->ToString(), "0xffffffff80010104");
176  UnitTest::Assert("3: cpu0.sp", cpu->GetVariable("sp")->ToString(), "0xffffffffa0007ed0");
177  UnitTest::Assert("3: cpu0.v0", cpu->GetVariable("v0")->ToString(), "0xffffffff88880000");
178  UnitTest::Assert("3: cpu0.v1", cpu->GetVariable("v1")->ToString(), "0xffffffffcccc0000");
179 
180  cmd->Execute(gxemul, dummyArguments);
181  UnitTest::Assert("root.step should be 2", gxemul.GetStep(), 2);
182  cpu = gxemul.GetRootComponent()->LookupPath("cpu0");
183  UnitTest::Assert("2: cpu0.pc", cpu->GetVariable("pc")->ToString(), "0xffffffff80010100");
184  UnitTest::Assert("2: cpu0.sp", cpu->GetVariable("sp")->ToString(), "0xffffffffa0007ed0");
185  UnitTest::Assert("2: cpu0.v0", cpu->GetVariable("v0")->ToString(), "0");
186  UnitTest::Assert("2: cpu0.v1", cpu->GetVariable("v1")->ToString(), "0xffffffffcccc0000");
187 
188  cmd->Execute(gxemul, dummyArguments);
189  UnitTest::Assert("root.step should be 1", gxemul.GetStep(), 1);
190  cpu = gxemul.GetRootComponent()->LookupPath("cpu0");
191  UnitTest::Assert("1: cpu0.pc", cpu->GetVariable("pc")->ToString(), "0xffffffff800100fc");
192  UnitTest::Assert("1: cpu0.sp", cpu->GetVariable("sp")->ToString(), "0xffffffffa0007ed0");
193  UnitTest::Assert("1: cpu0.v0", cpu->GetVariable("v0")->ToString(), "0");
194  UnitTest::Assert("1: cpu0.v1", cpu->GetVariable("v1")->ToString(), "0");
195 
196  cmd->Execute(gxemul, dummyArguments);
197  UnitTest::Assert("root.step should be 0", gxemul.GetStep(), 0);
198  cpu = gxemul.GetRootComponent()->LookupPath("cpu0");
199  UnitTest::Assert("0: cpu0.pc", cpu->GetVariable("pc")->ToString(), "0xffffffff800100f8");
200  UnitTest::Assert("0: cpu0.sp", cpu->GetVariable("sp")->ToString(), "0xffffffffa0007f00");
201  UnitTest::Assert("0: cpu0.v0", cpu->GetVariable("v0")->ToString(), "0");
202  UnitTest::Assert("0: cpu0.v1", cpu->GetVariable("v1")->ToString(), "0");
203 
204  cmd->Execute(gxemul, dummyArguments);
205  UnitTest::Assert("root.step should still be 0", gxemul.GetStep(), 0);
206  cpu = gxemul.GetRootComponent()->LookupPath("cpu0");
207  UnitTest::Assert("X: cpu0.pc", cpu->GetVariable("pc")->ToString(), "0xffffffff800100f8");
208  UnitTest::Assert("X: cpu0.sp", cpu->GetVariable("sp")->ToString(), "0xffffffffa0007f00");
209  UnitTest::Assert("X: cpu0.v0", cpu->GetVariable("v0")->ToString(), "0");
210  UnitTest::Assert("X: cpu0.v1", cpu->GetVariable("v1")->ToString(), "0");
211 }
212 
213 // Reset resets the component tree, but does not load back the binary!
214 static void Test_BackwardStepCommand_ManualAddAndLoad()
215 {
217  vector<string> dummyArguments;
218 
219  GXemul gxemul;
220 
221  gxemul.GetCommandInterpreter().RunCommand("add testmips");
222  gxemul.GetCommandInterpreter().RunCommand("load test/FileLoader_ELF_MIPS cpu0");
223  gxemul.SetSnapshottingEnabled(true);
224  gxemul.GetCommandInterpreter().RunCommand("step 3");
225  gxemul.Execute();
226 
227  UnitTest::Assert("root.step should initially be 3", gxemul.GetStep(), 3);
228 
230  UnitTest::Assert("3: cpu0.pc", cpu->GetVariable("pc")->ToString(), "0xffffffff80010104");
231  UnitTest::Assert("3: cpu0.sp", cpu->GetVariable("sp")->ToString(), "0xffffffffa0007ed0");
232  UnitTest::Assert("3: cpu0.v0", cpu->GetVariable("v0")->ToString(), "0xffffffff88880000");
233  UnitTest::Assert("3: cpu0.v1", cpu->GetVariable("v1")->ToString(), "0xffffffffcccc0000");
234 
235  cmd->Execute(gxemul, dummyArguments);
236  UnitTest::Assert("root.step should be 2", gxemul.GetStep(), 2);
237  cpu = gxemul.GetRootComponent()->LookupPath("cpu0");
238  UnitTest::Assert("2: cpu0.pc", cpu->GetVariable("pc")->ToString(), "0xffffffff80010100");
239  UnitTest::Assert("2: cpu0.sp", cpu->GetVariable("sp")->ToString(), "0xffffffffa0007ed0");
240  UnitTest::Assert("2: cpu0.v0", cpu->GetVariable("v0")->ToString(), "0");
241  UnitTest::Assert("2: cpu0.v1", cpu->GetVariable("v1")->ToString(), "0xffffffffcccc0000");
242 
243  cmd->Execute(gxemul, dummyArguments);
244  UnitTest::Assert("root.step should be 1", gxemul.GetStep(), 1);
245  cpu = gxemul.GetRootComponent()->LookupPath("cpu0");
246  UnitTest::Assert("1: cpu0.pc", cpu->GetVariable("pc")->ToString(), "0xffffffff800100fc");
247  UnitTest::Assert("1: cpu0.sp", cpu->GetVariable("sp")->ToString(), "0xffffffffa0007ed0");
248  UnitTest::Assert("1: cpu0.v0", cpu->GetVariable("v0")->ToString(), "0");
249  UnitTest::Assert("1: cpu0.v1", cpu->GetVariable("v1")->ToString(), "0");
250 
251  cmd->Execute(gxemul, dummyArguments);
252  UnitTest::Assert("root.step should be 0", gxemul.GetStep(), 0);
253  cpu = gxemul.GetRootComponent()->LookupPath("cpu0");
254  UnitTest::Assert("0: cpu0.pc", cpu->GetVariable("pc")->ToString(), "0xffffffff800100f8");
255  UnitTest::Assert("0: cpu0.sp", cpu->GetVariable("sp")->ToString(), "0xffffffffa0007f00");
256  UnitTest::Assert("0: cpu0.v0", cpu->GetVariable("v0")->ToString(), "0");
257  UnitTest::Assert("0: cpu0.v1", cpu->GetVariable("v1")->ToString(), "0");
258 
259  cmd->Execute(gxemul, dummyArguments);
260  UnitTest::Assert("root.step should still be 0", gxemul.GetStep(), 0);
261  cpu = gxemul.GetRootComponent()->LookupPath("cpu0");
262  UnitTest::Assert("X: cpu0.pc", cpu->GetVariable("pc")->ToString(), "0xffffffff800100f8");
263  UnitTest::Assert("X: cpu0.sp", cpu->GetVariable("sp")->ToString(), "0xffffffffa0007f00");
264  UnitTest::Assert("X: cpu0.v0", cpu->GetVariable("v0")->ToString(), "0");
265  UnitTest::Assert("X: cpu0.v1", cpu->GetVariable("v1")->ToString(), "0");
266 }
267 
269 {
270  UNITTEST(Test_BackwardStepCommand_AlreadyAtStep0);
271  UNITTEST(Test_BackwardStepCommand_NotWhenSnapshotsAreDisabled);
272  UNITTEST(Test_BackwardStepCommand_Basic);
273  UNITTEST(Test_BackwardStepCommand_ManualAddAndLoad);
274 }
275 
276 #endif
A Command which sets the RunState to BackwardsSingleStepping.
virtual void ShowDebugMessage(const string &msg)=0
Shows a debug message.
virtual bool Execute(GXemul &gxemul, const vector< string > &arguments)
Executes the command on a given GXemul instance.
StateVariable * GetVariable(const string &name)
Gets a pointer to a state variable.
Definition: Component.cc:949
virtual string GetLongDescription() const
Returns a long description/help message for the command.
bool Reset()
Resets the emulation.
Definition: GXemul.cc:700
const refcount_ptr< Component > LightClone() const
Makes a light clone of the component and all its children.
Definition: Component.cc:192
bool RunCommand(const string &command, bool *pSuccess=NULL)
Runs a command, given as a string.
BackwardStepCommand()
Constructs a BackwardStepCommand.
uint64_t GetStep() const
Gets the current step of the emulation.
Definition: GXemul.cc:637
void SetSnapshottingEnabled(bool enabled)
Sets whether or not to use snapshots.
Definition: GXemul.cc:778
void DetectChanges(const refcount_ptr< Component > &oldClone, ostream &changeMessages) const
Compare an older clone to the current tree, to find changes.
Definition: Component.cc:198
The main emulator class.
Definition: GXemul.h:54
#define UNITTESTS(class)
Helper for unit test case execution.
Definition: UnitTest.h:184
CommandInterpreter & GetCommandInterpreter()
Gets a reference to the CommandInterpreter.
Definition: GXemul.cc:631
virtual bool Execute(GXemul &gxemul, const vector< string > &arguments)=0
Executes the command on a given GXemul instance.
virtual string GetShortDescription() const
Returns a short (one-line) description of the command.
Definition: cpu.h:326
uint64_t ToInteger() const
Returns the variable as an unsignedinteger value.
StateVariables make up the persistent state of Component objects.
Definition: StateVariable.h:67
A Command is a named function, executed by the CommandInterpreter.
Definition: Command.h:48
static void Assert(const string &strFailMessage, bool condition)
Asserts that a boolean condition is correct.
Definition: UnitTest.cc:40
bool SetVariableValue(const string &name, const string &expression)
Sets a variable to a new value.
Definition: Component.cc:1030
refcount_ptr< Component > GetRootComponent()
Gets a pointer to the root configuration component.
Definition: GXemul.cc:667
UI * GetUI()
Gets a pointer to the GXemul instance&#39; active UI.
Definition: GXemul.cc:661
const refcount_ptr< Component > LookupPath(string path) const
Looks up a path from this Component, and returns a pointer to the found Component, if any.
Definition: Component.cc:778
void Execute(const int longestTotalRun=100000)
Run the emulation for "a while".
Definition: GXemul.cc:894
bool ParseFilenames(string templateMachine, int filenameCount, char *filenames[])
Parses command line arguments (file names).
Definition: GXemul.cc:427
#define UNITTEST(functionname)
Helper for unit test case execution.
Definition: UnitTest.h:217

Generated on Fri Dec 7 2018 19:52:23 for GXemul by doxygen 1.8.13