2 #ifndef ROSE_BinaryAnalysis_InstructionSemantics_TestSemantics_H
3 #define ROSE_BinaryAnalysis_InstructionSemantics_TestSemantics_H
4 #include <featureTests.h>
5 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
7 #include <Rose/BinaryAnalysis/BasicTypes.h>
8 #include <Rose/BinaryAnalysis/InstructionSemantics/BaseSemantics.h>
9 #include <Rose/CommandLine.h>
12 namespace BinaryAnalysis {
13 namespace InstructionSemantics {
27 template<
class SValuePtr,
class RegisterStatePtr,
class MemoryStatePtr,
class StatePtr,
class RiscOperatorsPtr>
30 typedef typename SValuePtr::Pointee SValue;
31 typedef typename RegisterStatePtr::element_type RegisterState;
32 typedef typename MemoryStatePtr::element_type MemoryState;
33 typedef typename StatePtr::element_type State;
34 typedef typename RiscOperatorsPtr::element_type RiscOperators;
41 void require(
bool assertion,
const std::string &what_failed) {
43 throw Exception(
"failed assertion: "+what_failed);
46 template<
typename Po
inter>
47 void nonnull(
const Pointer &x,
const std::string &what_failed) {
49 throw Exception(
"must not be null: "+what_failed);
53 template<
class ToPtr,
class FromPtr>
54 void check_type(
const FromPtr &x,
const std::string &what_failed) {
55 typedef typename ToPtr::element_type To;
56 nonnull(x, what_failed);
57 ToPtr y = boost::dynamic_pointer_cast<To>(x);
59 throw Exception(
"wrong pointer type: "+what_failed);
64 nonnull(x, what_failed);
65 SValuePtr y = BaseSemantics::dynamic_pointer_cast<SValue>(x);
67 throw Exception(
"wrong pointer type: "+what_failed);
81 : RegisterState(protoval, regdict) {}
88 : MemoryState(protoval) {}
94 StateSubclass(
const RegisterStatePtr ®isters,
const MemoryStatePtr &memory)
95 : State(registers, memory) {}
104 : RiscOperators(protoval, solver) {}
106 : RiscOperators(state, solver) {}
111 ByteOrder::Endianness savedByteOrder = ops->currentState()->memoryState()->get_byteOrder();
112 ops->currentState()->memoryState()->set_byteOrder(ByteOrder::ORDER_LSB);
113 test(ops->protoval(), ops->currentState(), ops);
114 ops->currentState()->memoryState()->set_byteOrder(ByteOrder::ORDER_MSB);
115 test(ops->protoval(), ops->currentState(), ops);
116 ops->currentState()->memoryState()->set_byteOrder(savedByteOrder);
132 require(v0==NULL,
"default SValue constructor");
135 check_sval_type(SValue::promote(protoval),
"SValue::promote()");
139 check_sval_type(v1,
"SValue::undefined_()");
140 require(v1->nBits()==8,
"SValue::undefined_() width");
144 check_sval_type(v1b,
"SValue::unspecified_()");
145 require(v1b->nBits()==8,
"SValue::unspecified() width");
152 check_sval_type(v2,
"SValue::number_()");
153 require(v2->nBits()==32,
"SValue::number_() width");
157 check_sval_type(v3,
"SValue::boolean_()");
158 require(v3->nBits()==1,
"SValue::boolean_() width");
162 check_sval_type(v4,
"SValue::copy()");
163 require(v4!=v3,
"SValue::copy() should have returned a new object");
164 require(v4->nBits()==1,
"SValue::copy() width");
165 require(v4->isConcrete() == v3->isConcrete(),
"copies should be identical");
166 if (v4->isConcrete())
167 require(v4->toUnsigned().get() == v3->toUnsigned().get(),
"concrete copies should be identical");
168 std::ostringstream v3str, v4str;
171 require(v3str.str() == v4str.str(),
"copies should be identical");
174 require(v3->mayEqual(v3),
"a value may_equal itself");
175 require(v3->mayEqual(v4),
"a value may_equal a copy of itself");
176 require(v4->mayEqual(v3),
"a value may_equal a copy of itself");
179 require(v3->mustEqual(v3),
"a value must_equal itself");
180 require(v3->mustEqual(v4) == v4->mustEqual(v3),
"must_equal should be symmetric");
189 check_type<RegisterStatePtr>(RegisterState::promote(rs1),
"RegisterState::promote()");
192 check_sval_type(rs1v1,
"RegisterState::protoval()");
196 check_type<RegisterStatePtr>(rs3,
"create()");
197 require(rs3->registerDictionary()==regdict,
"RegisterState::create() register dictionary");
198 require(rs3 != rs1,
"RegisterState::create() must return a new object");
200 check_sval_type(rs3v1,
"RegisterState::protoval() after create()");
203 check_type<RegisterStatePtr>(rs4,
"clone()");
204 require(rs4 != rs1,
"RegisterState::clone() must return a new object");
205 require(rs4->registerDictionary()==rs1->registerDictionary(),
206 "RegisterState::clone() must use the register dictionary from the source state");
208 check_sval_type(rs4v1,
"RegisterState::protoval() after clone()");
216 check_type<MemoryStatePtr>(MemoryState::promote(ms1),
"MemoryState::promote()");
219 check_sval_type(ms1v1,
"MemoryState::get_addr_protoval()");
222 check_sval_type(ms1v2,
"MemoryState::get_val_protoval()");
226 require(ms2 != ms1,
"MemoryState::create() must return a new state");
227 check_type<MemoryStatePtr>(ms2,
"MemoryState::create(protoval)");
229 check_sval_type(ms2v1,
"MemoryState::get_addr_protoval() after create");
231 check_sval_type(ms2v2,
"MemoryState::get_val_protoval() after create");
234 require(ms3 != ms1,
"MemoryState::clone must return a new state");
235 check_type<MemoryStatePtr>(ms3,
"MemoryState::clone()");
237 check_sval_type(ms3v1,
"MemoryState::get_addr_protoval() after clone");
239 check_sval_type(ms3v2,
"MemoryState::get_val_protoval() after clone");
246 check_type<StatePtr>(State::promote(state),
"State::promote()");
249 check_sval_type(state_protoval,
"State::protoval()");
253 require(s1 != state,
"State::create() must return a new state");
254 check_type<StatePtr>(s1,
"State::create(regs,mem)");
255 require(s1->registerState()==rs1,
"State::create() must use supplied register state");
256 require(s1->memoryState()==ms1,
"State::create() must use supplied memory state");
259 require(s2 != state,
"State::clone() must return a new state");
260 check_type<StatePtr>(s2,
"State::clone()");
261 require(s2->registerState() != state->registerState(),
262 "State::clone() must deep-copy the register state");
263 require(s2->memoryState() != state->memoryState(),
264 "State::clone() must deep-copy the memory state");
271 check_type<RiscOperatorsPtr>(RiscOperators::promote(ops),
"RiscOperators::promote()");
274 check_sval_type(ops_protoval,
"RiscOperators::protoval()");
278 require(o1 != ops,
"RiscOperators::create(protoval,solver) should return a new object");
279 check_type<RiscOperatorsPtr>(o1,
"RiscOperators::create(protoval,solver)");
282 require(o2 != ops,
"RiscOperators::create(state,solver) should return a new object");
283 check_type<RiscOperatorsPtr>(o2,
"RiscOperators::create(state,solver)");
286 check_type<StatePtr>(ops_orig_state,
"RiscOperators::currentState()");
293 ops->currentState(our_state);
294 require(ops->currentState() == our_state,
"RiscOperators::currentState failed to change state");
296 for (
size_t i=0; i<4; ++i) {
301 v32a = ops->undefined_(32);
302 v32b = ops->undefined_(32);
303 v8 = ops->undefined_(8);
304 v1 = ops->undefined_(1);
307 v32a = ops->undefined_(32);
308 v32b = ops->number_(32, 3);
309 v8 = ops->number_(8, 3);
310 v1 = ops->boolean_(
false);
313 v32a = ops->number_(32, 4);
314 v32b = ops->undefined_(32);
315 v8 = ops->undefined_(8);
316 v1 = ops->undefined_(1);
319 v32a = ops->number_(32, 4);
320 v32b = ops->number_(32, 3);
321 v8 = ops->number_(8, 3);
322 v1 = ops->boolean_(
true);
325 check_sval_type(v32a,
"RiscOperators value constructor");
326 require(v32a->nBits()==32,
"RiscOperators value constructor width");
327 check_sval_type(v32b,
"RiscOperators value constructor");
328 require(v32b->nBits()==32,
"RiscOperators value constructor width");
329 check_sval_type(v8,
"RiscOperators value constructor");
330 require(v8->nBits()==8,
"RiscOperators value constructor width");
331 check_sval_type(v1,
"RiscOperators value constructor");
332 require(v1->nBits()==1,
"RiscOperators value constructor width");
336 check_sval_type(ops_v4,
"RiscOperators::filterCallTarget");
337 require(ops_v4->nBits()==32,
"RiscOperators::filterCallTarget width");
340 check_sval_type(ops_v5,
"RiscOperators::filterReturnTarget");
341 require(ops_v5->nBits()==32,
"RiscOperators::filterReturnTarget width");
344 check_sval_type(ops_v6,
"RiscOperators::filterIndirectJumpTarget");
345 require(ops_v6->nBits()==32,
"RiscOperators::filterIndirectJumpTarget width");
348 check_sval_type(ops_v7,
"RiscOperators::rdtsc");
349 require(ops_v7->nBits()==64,
"RiscOperators::rdtsc width");
352 check_sval_type(ops_v8,
"RiscOperators::and_");
353 require(ops_v8->nBits()==32,
"RiscOperators::and_ width");
356 check_sval_type(ops_v9,
"RiscOperators::or_");
357 require(ops_v9->nBits()==32,
"RiscOperators::or_ width");
360 check_sval_type(ops_v10,
"RiscOperators::xor_");
361 require(ops_v10->nBits()==32,
"RiscOperators::xor_ width");
364 check_sval_type(ops_v11,
"RiscOperators::invert");
365 require(ops_v11->nBits()==32,
"RiscOperators::invert width");
368 check_sval_type(ops_v12,
"RiscOperators::extract");
369 require(ops_v12->nBits()==3,
"RiscOperators::extract width");
372 check_sval_type(ops_v13,
"RiscOperators::concat");
373 require(ops_v13->nBits()==64,
"RiscOperators::concat width");
376 check_sval_type(ops_v14,
"RiscOperators::leastSignificantSetBit");
377 require(ops_v14->nBits()==32,
"RiscOperators::leastSignificantSetBit width");
380 check_sval_type(ops_v15,
"RiscOperators::mostSignificantSetBit");
381 require(ops_v15->nBits()==32,
"RiscOperators::mostSignificantSetBit width");
384 check_sval_type(ops_v16,
"RiscOperators::rotateLeft");
385 require(ops_v16->nBits()==32,
"RiscOperators::rotateLeft width");
388 check_sval_type(ops_v17,
"RiscOperators::rotateRight");
389 require(ops_v17->nBits()==32,
"RiscOperators::rotateRight width");
392 check_sval_type(ops_v18,
"RiscOperators::shiftLeft");
393 require(ops_v18->nBits()==32,
"RiscOperators::shiftLeft width");
396 check_sval_type(ops_v19,
"RiscOperators::shiftRight");
397 require(ops_v19->nBits()==32,
"RiscOperators::shiftRight width");
400 check_sval_type(ops_v20,
"RiscOperators::shiftRightArithmetic");
401 require(ops_v20->nBits()==32,
"RiscOperators::shiftRightArithmetic width");
404 check_sval_type(ops_v21,
"RiscOperators::equalToZero");
405 require(ops_v21->nBits()==1,
"RiscOperators::equalToZero width");
408 check_sval_type(ops_v22,
"RiscOperators::ite");
409 require(ops_v22->nBits()==32,
"RiscOperators::ite width");
413 check_sval_type(ops_v22b,
"RiscOperators::iteWithStatus");
414 require(ops_v22b->nBits() == 32,
"RiscOperators::iteWithStatus width");
417 check_sval_type(ops_v23,
"RiscOperators::unsignedExtend");
418 require(ops_v23->nBits()==32,
"RiscOperators::unsignedExtend width");
421 check_sval_type(ops_v24,
"RiscOperators::unsignedExtend truncate");
422 require(ops_v24->nBits()==8,
"RiscOperators::unsignedExtend truncate width");
425 check_sval_type(ops_v25,
"RiscOperators::signExtend");
426 require(ops_v25->nBits()==32,
"RiscOperators::signExtend width");
429 check_sval_type(ops_v26,
"RiscOperators::add");
430 require(ops_v26->nBits()==32,
"RiscOperators::add width");
434 check_sval_type(ops_v27,
"RiscOperators::addWithCarries");
435 require(ops_v27->nBits()==32,
"RiscOperators::addWithCarries width");
436 check_sval_type(carry_out,
"RiscOperators::addWithCarries carry_out");
437 require(carry_out->nBits()==32,
"RiscOperators::addWithCarries carry_out width");
440 check_sval_type(ops_v28,
"RiscOperators::negate");
441 require(ops_v28->nBits()==32,
"RiscOperators::negate width");
445 check_sval_type(ops_v29,
"RiscOperators::signedDivide");
446 require(ops_v29->nBits()==32,
"RiscOperators::signedDivide width");
453 check_sval_type(ops_v30,
"RiscOperators::signedModulo");
454 require(ops_v30->nBits()==8,
"RiscOperators::signedModulo width");
460 check_sval_type(ops_v31,
"RiscOperators::signedMultiply");
461 require(ops_v31->nBits()==40,
"RiscOperators::signedMultiply width");
465 check_sval_type(ops_v32,
"RiscOperators::unsignedDivide");
466 require(ops_v32->nBits()==32,
"RiscOperators::unsignedDivide width");
473 check_sval_type(ops_v33,
"RiscOperators::unsignedModulo");
474 require(ops_v33->nBits()==8,
"RiscOperators::unsignedModulo width");
480 check_sval_type(ops_v34,
"RiscOperators::unsignedMultiply");
481 require(ops_v34->nBits()==40,
"RiscOperators::unsignedMultiply width");
484 check_sval_type(ops_v35,
"RiscOperators::readRegister");
485 require(ops_v35->nBits()==32,
"RiscOperators::readRegister width");
493 check_sval_type(ops_v36,
"RiscOperators::readMemory byte");
494 require(ops_v36->nBits()==8,
"RiscOperators::readMemory byte width");
498 check_sval_type(ops_v37,
"RiscOperators::readMemory word");
499 require(ops_v37->nBits()==32,
"RiscOperators::readMemory word width");
506 ops->writeMemory(RegisterDescriptor(), v32a, dflt32, v1);
511 ops->currentState(ops_orig_state);
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
Return value is formed from neither A nor B.
Provides functions for testing binary instruction semantics.
boost::shared_ptr< RegisterState > RegisterStatePtr
Shared-ownership pointer to a register state.
Main namespace for the ROSE library.
boost::shared_ptr< State > StatePtr
Shared-ownership pointer to a semantic state.
boost::shared_ptr< MemoryState > MemoryStatePtr
Shared-ownership pointer to a memory state.
IteStatus
Status for iteWithStatus operation.
static Ptr instance(const std::string &name)
Allocate a new solver by name.
Base class for exceptions thrown by instruction semantics.
Describes (part of) a physical CPU register.
std::shared_ptr< SmtSolver > SmtSolverPtr
Reference counting pointer.
static Ptr instancePentium4()
Intel Pentium 4 registers.
Base class for all ROSE exceptions.
ROSE_DLL_API GenericSwitchArgs genericSwitchArgs
Global location for parsed generic command-line switches.