ROSE  0.11.22.0
TestSemantics2.h
1 // Perform basic sanity checks on instruction semantics
2 #ifndef Rose_TestSemantics2_H
3 #define Rose_TestSemantics2_H
4 #include <featureTests.h>
5 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
6 
7 #include "BaseSemantics2.h"
8 #include "CommandLine.h"
9 
10 namespace Rose {
11 namespace BinaryAnalysis { // documented elsewhere
12 namespace InstructionSemantics2 { // documented elsewhere
13 
26 template<class SValuePtr, class RegisterStatePtr, class MemoryStatePtr, class StatePtr, class RiscOperatorsPtr>
28 public:
29  typedef typename SValuePtr::Pointee SValue;
30  typedef typename RegisterStatePtr::element_type RegisterState;
31  typedef typename MemoryStatePtr::element_type MemoryState;
32  typedef typename StatePtr::element_type State;
33  typedef typename RiscOperatorsPtr::element_type RiscOperators;
34 
36  public:
37  Exception(const std::string &mesg): BaseSemantics::Exception(mesg, NULL) {}
38  };
39 
40  void require(bool assertion, const std::string &what_failed) {
41  if (!assertion)
42  throw Exception("failed assertion: "+what_failed);
43  }
44 
45  template<typename Pointer>
46  void nonnull(const Pointer &x, const std::string &what_failed) {
47  if (x==NULL)
48  throw Exception("must not be null: "+what_failed);
49  }
50 
51  // check boost smart pointers
52  template<class ToPtr, class FromPtr>
53  void check_type(const FromPtr &x, const std::string &what_failed) {
54  typedef typename ToPtr::element_type To;
55  nonnull(x, what_failed);
56  ToPtr y = boost::dynamic_pointer_cast<To>(x);
57  if (y==NULL)
58  throw Exception("wrong pointer type: "+what_failed);
59  }
60 
61  // check SValue smart pointers
62  void check_sval_type(const BaseSemantics::SValuePtr &x, const std::string &what_failed) {
63  nonnull(x, what_failed);
64  SValuePtr y = BaseSemantics::dynamic_pointer_cast<SValue>(x);
65  if (y==NULL)
66  throw Exception("wrong pointer type: "+what_failed);
67  }
68 
69  // Compile-time checks for SValue
70  class SValueSubclass: public SValue {
71  public:
72  explicit SValueSubclass(size_t nbits): SValue(nbits) {}
73  SValueSubclass(const SValueSubclass &other): SValue(other) {}
74  };
75 
76  // Compile-time checks for RegisterState
77  class RegisterStateSubclass: public RegisterState {
78  public:
79  explicit RegisterStateSubclass(const SValuePtr &protoval, const RegisterDictionary *regdict)
80  : RegisterState(protoval, regdict) {}
81  };
82 
83  // Compile-time checks for MemoryState
84  class MemoryStateSubclass: public MemoryState {
85  public:
86  explicit MemoryStateSubclass(const SValuePtr &protoval)
87  : MemoryState(protoval) {}
88  };
89 
90  // Compile-time checks for State
91  class StateSubclass: public State {
92  public:
93  StateSubclass(const RegisterStatePtr &registers, const MemoryStatePtr &memory)
94  : State(registers, memory) {}
95  StateSubclass(const StateSubclass &other)
96  : State(other) {}
97  };
98 
99  // Compile-time checks for RiscOperators
100  class RiscOperatorsSubclass: public RiscOperators {
101  public:
102  explicit RiscOperatorsSubclass(const SValuePtr &protoval, const SmtSolverPtr &solver = SmtSolverPtr())
103  : RiscOperators(protoval, solver) {}
104  explicit RiscOperatorsSubclass(const StatePtr &state, const SmtSolverPtr &solver = SmtSolverPtr())
105  : RiscOperators(state, solver) {}
106  };
107 
108  // Run-time checks
109  void test(const BaseSemantics::RiscOperatorsPtr &ops) {
110  ByteOrder::Endianness savedByteOrder = ops->currentState()->memoryState()->get_byteOrder();
111  ops->currentState()->memoryState()->set_byteOrder(ByteOrder::ORDER_LSB);
112  test(ops->protoval(), ops->currentState(), ops);
113  ops->currentState()->memoryState()->set_byteOrder(ByteOrder::ORDER_MSB);
114  test(ops->protoval(), ops->currentState(), ops);
115  ops->currentState()->memoryState()->set_byteOrder(savedByteOrder);
116  }
117 
118  void test(const BaseSemantics::SValuePtr &protoval,
119  const BaseSemantics::StatePtr &state,
120  const BaseSemantics::RiscOperatorsPtr &ops) {
121 
123  const RegisterDescriptor reg32 = regdict->findOrThrow("eip");
125 
127  // SValue
129 
130  SValuePtr v0;
131  require(v0==NULL, "default SValue constructor");
132 
133  // Dynamic pointer casts
134  check_sval_type(SValue::promote(protoval), "SValue::promote()");
135 
136  // Virtual constructor: undefined_()
137  BaseSemantics::SValuePtr v1 = protoval->undefined_(8);
138  check_sval_type(v1, "SValue::undefined_()");
139  require(v1->get_width()==8, "SValue::undefined_() width");
140 
141  // Virtual constructor: unspecified_()
142  BaseSemantics::SValuePtr v1b = protoval->unspecified_(8);
143  check_sval_type(v1b, "SValue::unspecified_()");
144  require(v1b->get_width()==8, "SValue::unspecified() width");
145 
146  // Virtual constructor: number_(). Note that we can't check that the number is actually concrete and has a value
147  // because BaseSemantics defines only the API for is_number() and get_number() and not the semantics of those
148  // methods. In fact, the NullSemantics domain doesn't make any distinction between concrete and abstract values--it
149  // treats everything as abstract.
150  BaseSemantics::SValuePtr v2 = protoval->number_(32, 123);
151  check_sval_type(v2, "SValue::number_()");
152  require(v2->get_width()==32, "SValue::number_() width");
153 
154  // Virtual constructor: boolean_()
155  BaseSemantics::SValuePtr v3 = protoval->boolean_(true);
156  check_sval_type(v3, "SValue::boolean_()");
157  require(v3->get_width()==1, "SValue::boolean_() width");
158 
159  // Virtual constructor: copy()
160  BaseSemantics::SValuePtr v4 = v3->copy();
161  check_sval_type(v4, "SValue::copy()");
162  require(v4!=v3, "SValue::copy() should have returned a new object");
163  require(v4->get_width()==1, "SValue::copy() width");
164  require(v4->is_number() == v3->is_number(), "copies should be identical");
165  if (v4->is_number())
166  require(v4->get_number() == v3->get_number(), "concrete copies should be identical");
167  std::ostringstream v3str, v4str;
168  v3str <<*v3;
169  v4str <<*v4;
170  require(v3str.str() == v4str.str(), "copies should be identical");
171 
172  // may_equal
173  require(v3->may_equal(v3), "a value may_equal itself");
174  require(v3->may_equal(v4), "a value may_equal a copy of itself");
175  require(v4->may_equal(v3), "a value may_equal a copy of itself");
176 
177  // must_equal. Note: must_equal(v3, v4) need not be true when v4 is a copy of v3, although most subclasses do this.
178  require(v3->must_equal(v3), "a value must_equal itself");
179  require(v3->must_equal(v4) == v4->must_equal(v3), "must_equal should be symmetric");
180 
181 
183  // RegisterState (read/write is tested by RiscOperators)
185 
186  // Dynamic pointer cast
187  BaseSemantics::RegisterStatePtr rs1 = state->registerState();
188  check_type<RegisterStatePtr>(RegisterState::promote(rs1), "RegisterState::promote()");
189 
190  BaseSemantics::SValuePtr rs1v1 = rs1->protoval();
191  check_sval_type(rs1v1, "RegisterState::protoval()");
192 
193  // Virtual constructors
194  BaseSemantics::RegisterStatePtr rs3 = rs1->create(protoval, regdict);
195  check_type<RegisterStatePtr>(rs3, "create()");
196  require(rs3->get_register_dictionary()==regdict, "RegisterState::create() register dictionary");
197  require(rs3 != rs1, "RegisterState::create() must return a new object");
198  BaseSemantics::SValuePtr rs3v1 = rs3->protoval();
199  check_sval_type(rs3v1, "RegisterState::protoval() after create()");
200 
201  BaseSemantics::RegisterStatePtr rs4 = rs1->clone();
202  check_type<RegisterStatePtr>(rs4, "clone()");
203  require(rs4 != rs1, "RegisterState::clone() must return a new object");
204  require(rs4->get_register_dictionary()==rs1->get_register_dictionary(),
205  "RegisterState::clone() must use the register dictionary from the source state");
206  BaseSemantics::SValuePtr rs4v1 = rs4->protoval();
207  check_sval_type(rs4v1, "RegisterState::protoval() after clone()");
208 
210  // MemoryState (read/write is tested by RiscOperators)
212 
213  // Dynamic pointer cast
214  BaseSemantics::MemoryStatePtr ms1 = state->memoryState();
215  check_type<MemoryStatePtr>(MemoryState::promote(ms1), "MemoryState::promote()");
216 
217  BaseSemantics::SValuePtr ms1v1 = ms1->get_addr_protoval();
218  check_sval_type(ms1v1, "MemoryState::get_addr_protoval()");
219 
220  BaseSemantics::SValuePtr ms1v2 = ms1->get_val_protoval();
221  check_sval_type(ms1v2, "MemoryState::get_val_protoval()");
222 
223  // Virtual constructors
224  BaseSemantics::MemoryStatePtr ms2 = ms1->create(protoval, protoval);
225  require(ms2 != ms1, "MemoryState::create() must return a new state");
226  check_type<MemoryStatePtr>(ms2, "MemoryState::create(protoval)");
227  BaseSemantics::SValuePtr ms2v1 = ms2->get_addr_protoval();
228  check_sval_type(ms2v1, "MemoryState::get_addr_protoval() after create");
229  BaseSemantics::SValuePtr ms2v2 = ms2->get_val_protoval();
230  check_sval_type(ms2v2, "MemoryState::get_val_protoval() after create");
231 
232  BaseSemantics::MemoryStatePtr ms3 = ms1->clone();
233  require(ms3 != ms1, "MemoryState::clone must return a new state");
234  check_type<MemoryStatePtr>(ms3, "MemoryState::clone()");
235  BaseSemantics::SValuePtr ms3v1 = ms3->get_addr_protoval();
236  check_sval_type(ms3v1, "MemoryState::get_addr_protoval() after clone");
237  BaseSemantics::SValuePtr ms3v2 = ms3->get_val_protoval();
238  check_sval_type(ms3v2, "MemoryState::get_val_protoval() after clone");
239 
241  // State (read/write is tested by RiscOperators)
243 
244  // Dynamic pointer casts
245  check_type<StatePtr>(State::promote(state), "State::promote()");
246 
247  BaseSemantics::SValuePtr state_protoval = state->protoval();
248  check_sval_type(state_protoval, "State::protoval()");
249 
250  // Virtual constructors
251  BaseSemantics::StatePtr s1 = state->create(rs1, ms1);
252  require(s1 != state, "State::create() must return a new state");
253  check_type<StatePtr>(s1, "State::create(regs,mem)");
254  require(s1->registerState()==rs1, "State::create() must use supplied register state");
255  require(s1->memoryState()==ms1, "State::create() must use supplied memory state");
256 
257  BaseSemantics::StatePtr s2 = state->clone();
258  require(s2 != state, "State::clone() must return a new state");
259  check_type<StatePtr>(s2, "State::clone()");
260  require(s2->registerState() != state->registerState(),
261  "State::clone() must deep-copy the register state");
262  require(s2->memoryState() != state->memoryState(),
263  "State::clone() must deep-copy the memory state");
264 
266  // RiscOperators
268 
269  // Dynamic pointer casts
270  check_type<RiscOperatorsPtr>(RiscOperators::promote(ops), "RiscOperators::promote()");
271 
272  BaseSemantics::SValuePtr ops_protoval = ops->protoval();
273  check_sval_type(ops_protoval, "RiscOperators::protoval()");
274 
275  // Virtual constructors
276  BaseSemantics::RiscOperatorsPtr o1 = ops->create(protoval, solver);
277  require(o1 != ops, "RiscOperators::create(protoval,solver) should return a new object");
278  check_type<RiscOperatorsPtr>(o1, "RiscOperators::create(protoval,solver)");
279 
280  BaseSemantics::RiscOperatorsPtr o2 = ops->create(state, solver);
281  require(o2 != ops, "RiscOperators::create(state,solver) should return a new object");
282  check_type<RiscOperatorsPtr>(o2, "RiscOperators::create(state,solver)");
283 
284  BaseSemantics::StatePtr ops_orig_state = ops->currentState();
285  check_type<StatePtr>(ops_orig_state, "RiscOperators::currentState()");
286 
287  // We shouldn't use the supplied state because these tests modify it. So we'll make a copy of the state and use that,
288  // and then restore the original state before we return (but leave our state there fore debugging if there's an
289  // exception). This has the side effect of implicitly checking that State::clone() works because if it didn't the
290  // caller would see the mess we made here. State::clone was tested already.
291  BaseSemantics::StatePtr our_state = ops_orig_state->clone();
292  ops->currentState(our_state);
293  require(ops->currentState() == our_state, "RiscOperators::currentState failed to change state");
294 
295  for (size_t i=0; i<4; ++i) {
296  // Value-creating operators
297  BaseSemantics::SValuePtr v32a, v32b, v8, v1;
298  switch (i) {
299  case 0:
300  v32a = ops->undefined_(32);
301  v32b = ops->undefined_(32);
302  v8 = ops->undefined_(8);
303  v1 = ops->undefined_(1);
304  break;
305  case 1:
306  v32a = ops->undefined_(32);
307  v32b = ops->number_(32, 3);
308  v8 = ops->number_(8, 3);
309  v1 = ops->boolean_(false);
310  break;
311  case 2:
312  v32a = ops->number_(32, 4);
313  v32b = ops->undefined_(32);
314  v8 = ops->undefined_(8);
315  v1 = ops->undefined_(1);
316  break;
317  case 3:
318  v32a = ops->number_(32, 4);
319  v32b = ops->number_(32, 3);
320  v8 = ops->number_(8, 3);
321  v1 = ops->boolean_(true);
322  break;
323  }
324  check_sval_type(v32a, "RiscOperators value constructor");
325  require(v32a->get_width()==32, "RiscOperators value constructor width");
326  check_sval_type(v32b, "RiscOperators value constructor");
327  require(v32b->get_width()==32, "RiscOperators value constructor width");
328  check_sval_type(v8, "RiscOperators value constructor");
329  require(v8->get_width()==8, "RiscOperators value constructor width");
330  check_sval_type(v1, "RiscOperators value constructor");
331  require(v1->get_width()==1, "RiscOperators value constructor width");
332 
333  // x86-specific operators
334  BaseSemantics::SValuePtr ops_v4 = ops->filterCallTarget(v32a);
335  check_sval_type(ops_v4, "RiscOperators::filterCallTarget");
336  require(ops_v4->get_width()==32, "RiscOperators::filterCallTarget width");
337 
338  BaseSemantics::SValuePtr ops_v5 = ops->filterReturnTarget(v32a);
339  check_sval_type(ops_v5, "RiscOperators::filterReturnTarget");
340  require(ops_v5->get_width()==32, "RiscOperators::filterReturnTarget width");
341 
342  BaseSemantics::SValuePtr ops_v6 = ops->filterIndirectJumpTarget(v32a);
343  check_sval_type(ops_v6, "RiscOperators::filterIndirectJumpTarget");
344  require(ops_v6->get_width()==32, "RiscOperators::filterIndirectJumpTarget width");
345 
346  BaseSemantics::SValuePtr ops_v7 = ops->rdtsc();
347  check_sval_type(ops_v7, "RiscOperators::rdtsc");
348  require(ops_v7->get_width()==64, "RiscOperators::rdtsc width");
349 
350  BaseSemantics::SValuePtr ops_v8 = ops->and_(v32a, v32b);
351  check_sval_type(ops_v8, "RiscOperators::and_");
352  require(ops_v8->get_width()==32, "RiscOperators::and_ width");
353 
354  BaseSemantics::SValuePtr ops_v9 = ops->or_(v32a, v32b);
355  check_sval_type(ops_v9, "RiscOperators::or_");
356  require(ops_v9->get_width()==32, "RiscOperators::or_ width");
357 
358  BaseSemantics::SValuePtr ops_v10 = ops->xor_(v32a, v32b);
359  check_sval_type(ops_v10, "RiscOperators::xor_");
360  require(ops_v10->get_width()==32, "RiscOperators::xor_ width");
361 
362  BaseSemantics::SValuePtr ops_v11 = ops->invert(v32a);
363  check_sval_type(ops_v11, "RiscOperators::invert");
364  require(ops_v11->get_width()==32, "RiscOperators::invert width");
365 
366  BaseSemantics::SValuePtr ops_v12 = ops->extract(v32a, 5, 8);
367  check_sval_type(ops_v12, "RiscOperators::extract");
368  require(ops_v12->get_width()==3, "RiscOperators::extract width");
369 
370  BaseSemantics::SValuePtr ops_v13 = ops->concat(v32a, v32b);
371  check_sval_type(ops_v13, "RiscOperators::concat");
372  require(ops_v13->get_width()==64, "RiscOperators::concat width");
373 
374  BaseSemantics::SValuePtr ops_v14 = ops->leastSignificantSetBit(v32a);
375  check_sval_type(ops_v14, "RiscOperators::leastSignificantSetBit");
376  require(ops_v14->get_width()==32, "RiscOperators::leastSignificantSetBit width");
377 
378  BaseSemantics::SValuePtr ops_v15 = ops->mostSignificantSetBit(v32a);
379  check_sval_type(ops_v15, "RiscOperators::mostSignificantSetBit");
380  require(ops_v15->get_width()==32, "RiscOperators::mostSignificantSetBit width");
381 
382  BaseSemantics::SValuePtr ops_v16 = ops->rotateLeft(v32a, v8);
383  check_sval_type(ops_v16, "RiscOperators::rotateLeft");
384  require(ops_v16->get_width()==32, "RiscOperators::rotateLeft width");
385 
386  BaseSemantics::SValuePtr ops_v17 = ops->rotateRight(v32a, v8);
387  check_sval_type(ops_v17, "RiscOperators::rotateRight");
388  require(ops_v17->get_width()==32, "RiscOperators::rotateRight width");
389 
390  BaseSemantics::SValuePtr ops_v18 = ops->shiftLeft(v32a, v8);
391  check_sval_type(ops_v18, "RiscOperators::shiftLeft");
392  require(ops_v18->get_width()==32, "RiscOperators::shiftLeft width");
393 
394  BaseSemantics::SValuePtr ops_v19 = ops->shiftRight(v32a, v8);
395  check_sval_type(ops_v19, "RiscOperators::shiftRight");
396  require(ops_v19->get_width()==32, "RiscOperators::shiftRight width");
397 
398  BaseSemantics::SValuePtr ops_v20 = ops->shiftRightArithmetic(v32a, v8);
399  check_sval_type(ops_v20, "RiscOperators::shiftRightArithmetic");
400  require(ops_v20->get_width()==32, "RiscOperators::shiftRightArithmetic width");
401 
402  BaseSemantics::SValuePtr ops_v21 = ops->equalToZero(v32a);
403  check_sval_type(ops_v21, "RiscOperators::equalToZero");
404  require(ops_v21->get_width()==1, "RiscOperators::equalToZero width");
405 
406  BaseSemantics::SValuePtr ops_v22 = ops->ite(v1, v32a, v32b);
407  check_sval_type(ops_v22, "RiscOperators::ite");
408  require(ops_v22->get_width()==32, "RiscOperators::ite width");
409 
410  BaseSemantics::SValuePtr ops_v23 = ops->unsignedExtend(v8, 32);
411  check_sval_type(ops_v23, "RiscOperators::unsignedExtend");
412  require(ops_v23->get_width()==32, "RiscOperators::unsignedExtend width");
413 
414  BaseSemantics::SValuePtr ops_v24 = ops->unsignedExtend(v32a, 8);
415  check_sval_type(ops_v24, "RiscOperators::unsignedExtend truncate");
416  require(ops_v24->get_width()==8, "RiscOperators::unsignedExtend truncate width");
417 
418  BaseSemantics::SValuePtr ops_v25 = ops->signExtend(v8, 32);
419  check_sval_type(ops_v25, "RiscOperators::signExtend");
420  require(ops_v25->get_width()==32, "RiscOperators::signExtend width");
421 
422  BaseSemantics::SValuePtr ops_v26 = ops->add(v32a, v32b);
423  check_sval_type(ops_v26, "RiscOperators::add");
424  require(ops_v26->get_width()==32, "RiscOperators::add width");
425 
426  BaseSemantics::SValuePtr carry_out;
427  BaseSemantics::SValuePtr ops_v27 = ops->addWithCarries(v32a, v32b, v1, carry_out);
428  check_sval_type(ops_v27, "RiscOperators::addWithCarries");
429  require(ops_v27->get_width()==32, "RiscOperators::addWithCarries width");
430  check_sval_type(carry_out, "RiscOperators::addWithCarries carry_out");
431  require(carry_out->get_width()==32, "RiscOperators::addWithCarries carry_out width");
432 
433  BaseSemantics::SValuePtr ops_v28 = ops->negate(v32a);
434  check_sval_type(ops_v28, "RiscOperators::negate");
435  require(ops_v28->get_width()==32, "RiscOperators::negate width");
436 
437  try {
438  BaseSemantics::SValuePtr ops_v29 = ops->signedDivide(v32a, v8);
439  check_sval_type(ops_v29, "RiscOperators::signedDivide");
440  require(ops_v29->get_width()==32, "RiscOperators::signedDivide width");
441  } catch (const BaseSemantics::Exception&) {
442  // possible division by zero
443  }
444 
445  try {
446  BaseSemantics::SValuePtr ops_v30 = ops->signedModulo(v32a, v8);
447  check_sval_type(ops_v30, "RiscOperators::signedModulo");
448  require(ops_v30->get_width()==8, "RiscOperators::signedModulo width");
449  } catch (const BaseSemantics::Exception&) {
450  // possible division by zero
451  }
452 
453  BaseSemantics::SValuePtr ops_v31 = ops->signedMultiply(v32a, v8);
454  check_sval_type(ops_v31, "RiscOperators::signedMultiply");
455  require(ops_v31->get_width()==40, "RiscOperators::signedMultiply width");
456 
457  try {
458  BaseSemantics::SValuePtr ops_v32 = ops->unsignedDivide(v32a, v8);
459  check_sval_type(ops_v32, "RiscOperators::unsignedDivide");
460  require(ops_v32->get_width()==32, "RiscOperators::unsignedDivide width");
461  } catch (const BaseSemantics::Exception&) {
462  // possible division by zero
463  }
464 
465  try {
466  BaseSemantics::SValuePtr ops_v33 = ops->unsignedModulo(v32a, v8);
467  check_sval_type(ops_v33, "RiscOperators::unsignedModulo");
468  require(ops_v33->get_width()==8, "RiscOperators::unsignedModulo width");
469  } catch (const BaseSemantics::Exception&) {
470  // possible division by zero
471  }
472 
473  BaseSemantics::SValuePtr ops_v34 = ops->unsignedMultiply(v32a, v8);
474  check_sval_type(ops_v34, "RiscOperators::unsignedMultiply");
475  require(ops_v34->get_width()==40, "RiscOperators::unsignedMultiply width");
476 
477  BaseSemantics::SValuePtr ops_v35 = ops->readRegister(reg32);
478  check_sval_type(ops_v35, "RiscOperators::readRegister");
479  require(ops_v35->get_width()==32, "RiscOperators::readRegister width");
480 
481  // We can't really check many semantics for readMemory because each MemoryState might behave differently. For
482  // example, we can't check that reading the same address twice in a row returns the same value both times because
483  // the NullSemantics doesn't have this property.
484 
485  BaseSemantics::SValuePtr dflt8 = ops->number_(8, 0);
486  BaseSemantics::SValuePtr ops_v36 = ops->readMemory(RegisterDescriptor(), v32a, dflt8, v1);
487  check_sval_type(ops_v36, "RiscOperators::readMemory byte");
488  require(ops_v36->get_width()==8, "RiscOperators::readMemory byte width");
489 
490  BaseSemantics::SValuePtr dflt32 = ops->number_(32, 0);
491  BaseSemantics::SValuePtr ops_v37 = ops->readMemory(RegisterDescriptor(), v32a, dflt32, v1);
492  check_sval_type(ops_v37, "RiscOperators::readMemory word");
493  require(ops_v37->get_width()==32, "RiscOperators::readMemory word width");
494 
495  // Nothing to check for write memory other than that we can actually call it. The problem is that writeMemory only
496  // modifies a state and doesn't return anything we can test. The specifics of how it modifies a memory state is
497  // entirely up to the implementation, so we can't even test that writing a value to an address and then reading
498  // from that address returns the value that was written (e.g., NullSemantics doesn't have this property).
499 
500  ops->writeMemory(RegisterDescriptor(), v32a, dflt32, v1);
501 
502  }
503 
504  // Restore the original state
505  ops->currentState(ops_orig_state);
506  }
507 };
508 
509 } // namespace
510 } // namespace
511 } // namespace
512 
513 #endif
514 #endif
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
boost::shared_ptr< MemoryState > MemoryStatePtr
Shared-ownership pointer to a memory state.
boost::shared_ptr< State > StatePtr
Shared-ownership pointer to a semantic state.
RegisterDescriptor findOrThrow(const std::string &name) const
Find a register by name.
static const RegisterDictionary * dictionary_pentium4()
Intel Pentium 4 registers.
Main namespace for the ROSE library.
Sawyer::SharedPointer< class SmtSolver > SmtSolverPtr
Reference-counting pointer for SMT solvers.
static Ptr instance(const std::string &name)
Allocate a new solver by name.
Describes (part of) a physical CPU register.
Defines registers available for a particular architecture.
Definition: Registers.h:38
Base class for all ROSE exceptions.
Definition: RoseException.h:9
Base class for exceptions thrown by instruction semantics.
ROSE_DLL_API GenericSwitchArgs genericSwitchArgs
Global location for parsed generic command-line switches.
boost::shared_ptr< RegisterState > RegisterStatePtr
Shared-ownership pointer to a register state.
Provides functions for testing binary instruction semantics.