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