ROSE  0.11.52.0
NativeSemantics.h
1 #ifndef ROSE_BinaryAnalysis_InstructionSemantics2_NativeSemantics_H
2 #define ROSE_BinaryAnalysis_InstructionSemantics2_NativeSemantics_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
5 
6 #include <Rose/BinaryAnalysis/Debugger.h>
7 #include <Rose/BinaryAnalysis/InstructionSemantics2/ConcreteSemantics.h>
8 
9 #include <boost/noncopyable.hpp>
10 #include <boost/filesystem.hpp>
11 
12 namespace Rose {
13 namespace BinaryAnalysis {
14 namespace InstructionSemantics2 {
15 
17 namespace NativeSemantics {
18 
20 // Value type
22 
25 
28 
31 
33 // Register state
35 
37 typedef boost::shared_ptr<class RegisterState> RegisterStatePtr;
38 
42 class RegisterState: public BaseSemantics::RegisterState, boost::noncopyable {
43 public:
46 
49 
50 private:
51  Debugger::Ptr process_;
52 
53  //----------------------------------------
54  // Real constructors
55  //----------------------------------------
56 protected:
57  RegisterState() {}
58 
60  : BaseSemantics::RegisterState(protoval, process->registerDictionary()), process_(process) {
61  ASSERT_not_null(process);
62  }
63 
64  //----------------------------------------
65  // Static allocating constructors
66  //----------------------------------------
67 public:
69  static RegisterStatePtr instance() {
70  return RegisterStatePtr(new RegisterState);
71  }
72 
74  static RegisterStatePtr instance(const BaseSemantics::SValuePtr &protoval, const Debugger::Ptr &process) {
75  ASSERT_not_null(protoval);
76  (void) SValue::promote(protoval);
77  return RegisterStatePtr(new RegisterState(protoval, process));
78  }
79 
80  //----------------------------------------
81  // Virtual constructors
82  //----------------------------------------
83 public:
85  const RegisterDictionary *regdict) const ROSE_OVERRIDE {
86  ASSERT_not_implemented("not applicable for this class");
87  }
88 
89  virtual BaseSemantics::RegisterStatePtr clone() const ROSE_OVERRIDE {
90  ASSERT_not_implemented("not applicable for this class");
91  }
92 
93  //----------------------------------------
94  // Dynamic pointer casts
95  //----------------------------------------
96 public:
97  static RegisterStatePtr promote(const BaseSemantics::RegisterStatePtr &x) {
98  RegisterStatePtr retval = boost::dynamic_pointer_cast<RegisterState>(x);
99  ASSERT_not_null(retval);
100  return retval;
101  }
102 
103  //----------------------------------------
104  // Additional properties
105  //----------------------------------------
106 public:
109  return process_;
110  }
111 
112  //----------------------------------------
113  // Virtual function implementations
114  //----------------------------------------
115 public:
116  virtual void clear() ROSE_OVERRIDE {}
117 
118  virtual void zero() ROSE_OVERRIDE {
119  TODO("[Robb Matzke 2019-09-05]"); // set all registers to zero
120  }
121 
122  virtual bool merge(const BaseSemantics::RegisterStatePtr &other, BaseSemantics::RiscOperators *ops) ROSE_OVERRIDE {
123  ASSERT_not_implemented("[Robb Matzke 2019-09-05]");
124  }
125 
127  BaseSemantics::RiscOperators *ops) ROSE_OVERRIDE {
128  return peekRegister(reg, dflt, ops);
129  }
130 
132  BaseSemantics::RiscOperators*) ROSE_OVERRIDE;
133 
134  virtual void writeRegister(RegisterDescriptor, const BaseSemantics::SValuePtr &value,
135  BaseSemantics::RiscOperators*) ROSE_OVERRIDE;
136 
137  virtual void hash(Combinatorics::Hasher&, BaseSemantics::RiscOperators*) const override;
138 
139  virtual void print(std::ostream&, Formatter&) const ROSE_OVERRIDE;
140 };
141 
143 // Memory state
145 
147 typedef boost::shared_ptr<class MemoryState> MemoryStatePtr;
148 
152 class MemoryState: public BaseSemantics::MemoryState, boost::noncopyable {
153 public:
156 
159 
160 private:
161  Debugger::Ptr process_;
162 
163  //----------------------------------------
164  // Real constructors
165  //----------------------------------------
166 protected:
167  MemoryState() {}
168 
169  MemoryState(const BaseSemantics::SValuePtr &addrProtoval, const BaseSemantics::SValuePtr &valProtoval,
170  const Debugger::Ptr &process)
171  : BaseSemantics::MemoryState(addrProtoval, valProtoval), process_(process) {
172  ASSERT_not_null(process);
173  }
174 
175  //----------------------------------------
176  // Static allocating constructors
177  //----------------------------------------
178 public:
180  static MemoryStatePtr instance() {
181  return MemoryStatePtr(new MemoryState);
182  }
183 
185  static MemoryStatePtr instance(const BaseSemantics::SValuePtr &addrProtoval, const BaseSemantics::SValuePtr &valProtoval,
186  const Debugger::Ptr &process) {
187  return MemoryStatePtr(new MemoryState(addrProtoval, valProtoval, process));
188  }
189 
190  //----------------------------------------
191  // Virtual constructors
192  //----------------------------------------
193 public:
195  const BaseSemantics::SValuePtr &valProtoval) const ROSE_OVERRIDE {
196  ASSERT_not_implemented("not applicable for this class");
197  }
198 
199  virtual BaseSemantics::MemoryStatePtr clone() const ROSE_OVERRIDE {
200  ASSERT_not_implemented("not applicable for this class");
201  }
202 
203  //----------------------------------------
204  // Dynamic pointer casts
205  //----------------------------------------
206 public:
207  static MemoryStatePtr promote(const BaseSemantics::MemoryStatePtr &x) {
208  MemoryStatePtr retval = boost::dynamic_pointer_cast<MemoryState>(x);
209  ASSERT_not_null(retval);
210  return retval;
211  }
212 
213  //----------------------------------------
214  // Additional properties
215  //----------------------------------------
216 public:
219  return process_;
220  }
221 
222  //----------------------------------------
223  // Virtual function implementations
224  //----------------------------------------
225 public:
226  virtual void clear() ROSE_OVERRIDE {}
227 
229  BaseSemantics::RiscOperators *valOps) ROSE_OVERRIDE {
230  ASSERT_not_implemented("not applicable for this class");
231  }
232 
235  BaseSemantics::RiscOperators *valOps) ROSE_OVERRIDE {
236  return peekMemory(address, dflt, addrOps, valOps);
237  }
238 
239  virtual BaseSemantics::SValuePtr peekMemory(const BaseSemantics::SValuePtr &address, const BaseSemantics::SValuePtr &dflt,
241  BaseSemantics::RiscOperators *valOps) ROSE_OVERRIDE;
242 
243  virtual void writeMemory(const BaseSemantics::SValuePtr &addr, const BaseSemantics::SValuePtr &value,
244  BaseSemantics::RiscOperators *addrOps, BaseSemantics::RiscOperators *valOps) ROSE_OVERRIDE {
245  ASSERT_not_implemented("[Robb Matzke 2019-09-05]");
246  }
247 
249  BaseSemantics::RiscOperators *valOps) const override {
250  ASSERT_not_implemented("[Robb Matzke 2021-03-26]");
251  }
252 
253  virtual void print(std::ostream&, BaseSemantics::Formatter&) const ROSE_OVERRIDE {
254  ASSERT_not_implemented("[Robb Matzke 2019-09-05]");
255  }
256 };
257 
259 // Complete semantic state
261 
263 typedef boost::shared_ptr<class State> StatePtr;
264 
269 class State: public ConcreteSemantics::State, boost::noncopyable {
270 public:
273 
275  using Ptr = StatePtr;
276 
277  //----------------------------------------
278  // Real constructors
279  //----------------------------------------
280 protected:
282  : ConcreteSemantics::State(registers, memory) {
283  (void) RegisterState::promote(registers);
284  (void) MemoryState::promote(memory);
285  }
286 
287  //----------------------------------------
288  // Static allocating constructors
289  //----------------------------------------
290 public:
291  static StatePtr instance(const BaseSemantics::RegisterStatePtr &registers, const BaseSemantics::MemoryStatePtr &memory) {
292  return StatePtr(new State(registers, memory));
293  }
294 };
295 
297 // RISC operators
299 
301 typedef boost::shared_ptr<class RiscOperators> RiscOperatorsPtr;
302 
304 public:
307 
310 
311  //----------------------------------------
312  // Real constructors
313  //----------------------------------------
314 protected:
315  explicit RiscOperators(const BaseSemantics::StatePtr &state)
316  : ConcreteSemantics::RiscOperators(state, SmtSolverPtr()) {
317  name("Native");
318  }
319 
320  //----------------------------------------
321  // Static allocating constructors
322  //----------------------------------------
323 public:
328  static RiscOperatorsPtr instance(const BaseSemantics::SValuePtr &protoval, const Debugger::Ptr &process) {
329  RegisterStatePtr registers = RegisterState::instance(protoval, process);
330  MemoryStatePtr memory = MemoryState::instance(protoval, protoval, process);
331  StatePtr state = State::instance(registers, memory);
332  return RiscOperatorsPtr(new RiscOperators(state));
333  }
334 
340  static RiscOperatorsPtr instance(const BaseSemantics::StatePtr &state) {
341  (void) State::promote(state); // check that it's the correct type
342  return RiscOperatorsPtr(new RiscOperators(state));
343  }
344 
345  //----------------------------------------
346  // Virtual constructors
347  //----------------------------------------
348 public:
350  const SmtSolverPtr &solver = SmtSolverPtr()) const ROSE_OVERRIDE {
351  TODO("[Robb Matzke 2019-09-05]");
352  }
353 
354  //----------------------------------------
355  // Dynamic pointer casts
356  //----------------------------------------
357 public:
360  static RiscOperatorsPtr promote(const BaseSemantics::RiscOperatorsPtr &x) {
361  RiscOperatorsPtr retval = boost::dynamic_pointer_cast<RiscOperators>(x);
362  ASSERT_not_null(retval);
363  return retval;
364  }
365 
366  //----------------------------------------
367  // Additional properties
368  //----------------------------------------
369 public:
374  return RegisterState::promote(currentState()->registerState())->process();
375  }
376 };
377 
379 // Dispatcher
381 
383 typedef boost::shared_ptr<class Dispatcher> DispatcherPtr;
384 
386 public:
389 
392 
393 private:
394  Debugger::Ptr process_;
395 
396  //----------------------------------------
397  // Real constructors
398  //----------------------------------------
399 protected:
401  : process_(process) {
402  registerDictionary(process_->registerDictionary());
403  addressWidth(process_->kernelWordSize());
404  operators(RiscOperators::instance(protoval, process_));
405  }
406 
408  : process_(RiscOperators::promote(ops)->process()) {
409  registerDictionary(process_->registerDictionary());
410  addressWidth(process_->kernelWordSize());
411  operators(ops);
412  }
413 
414  //----------------------------------------
415  // Static allocating constructors
416  //----------------------------------------
417 public:
419  static DispatcherPtr instance(const Debugger::Ptr &process,
421  return DispatcherPtr(new Dispatcher(process, protoval));
422  }
423 
425  static DispatcherPtr instance(const Debugger::Specimen &specimen,
427  Debugger::Ptr process = Debugger::instance(specimen);
428  return DispatcherPtr(new Dispatcher(process, protoval));
429  }
430 
434  static DispatcherPtr instance(const BaseSemantics::RiscOperatorsPtr &ops) {
435  (void) RiscOperators::promote(ops); // check type
436  return DispatcherPtr(new Dispatcher(ops));
437  }
438 
439  //----------------------------------------
440  // Virtual constructors
441  //----------------------------------------
442 public:
444  create(const BaseSemantics::RiscOperatorsPtr &ops, size_t addrWidth=0,
445  const RegisterDictionary *regs=NULL) const ROSE_OVERRIDE {
446  notApplicable("create");
447  }
448 
449  //----------------------------------------
450  // Operations
451  //----------------------------------------
452 public:
461  virtual void processInstruction(SgAsmInstruction *insn) ROSE_OVERRIDE;
462  void processInstruction(rose_addr_t va);
468  virtual SgAsmInstruction* currentInstruction() const ROSE_OVERRIDE;
469 
470  virtual RegisterDescriptor instructionPointerRegister() const ROSE_OVERRIDE;
471  virtual RegisterDescriptor stackPointerRegister() const ROSE_OVERRIDE;
472  virtual RegisterDescriptor stackFrameRegister() const ROSE_OVERRIDE;
473  virtual RegisterDescriptor callReturnRegister() const ROSE_OVERRIDE;
474 
478  virtual void iprocReplace(SgAsmInstruction*, BaseSemantics::InsnProcessor*) ROSE_OVERRIDE {
479  notApplicable("iprocReplace");
480  }
481  virtual void iprocSet(int key, BaseSemantics::InsnProcessor*) ROSE_OVERRIDE {
482  notApplicable("iprocSet");
483  }
484  virtual int iprocKey(SgAsmInstruction*) const ROSE_OVERRIDE {
485  notApplicable("iprocKey");
486  }
489 private:
490  void notApplicable(const std::string &what) const SAWYER_ATTR_NORETURN {
491  ASSERT_not_implemented(what + " is not applicable for this class");
492  }
493 };
494 
495 
496 } // namespace
497 } // namespace
498 } // namespace
499 } // namespace
500 
501 #endif
502 #endif
Debugger::Ptr process() const
Property: Subordinate process storing the registers.
static RegisterStatePtr instance()
Construct a state not attached to any subordinate process.
Defines RISC operators for the ConcreteSemantics domain.
boost::shared_ptr< RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to a RISC operators object.
virtual BaseSemantics::SValuePtr readRegister(RegisterDescriptor reg, const BaseSemantics::SValuePtr &dflt, BaseSemantics::RiscOperators *ops) ROSE_OVERRIDE
Read a value from a register.
Debugger::Ptr process() const
Property: Subordinate process storing the registers.
virtual void print(std::ostream &, BaseSemantics::Formatter &) const ROSE_OVERRIDE
Print a memory state to more than one line of output.
virtual void print(std::ostream &, Formatter &) const ROSE_OVERRIDE
Print the register contents.
ConcreteSemantics::Formatter Formatter
Formatter for printing values.
static SValuePtr instance()
Instantiate a new prototypical value.
virtual BaseSemantics::SValuePtr peekRegister(RegisterDescriptor, const BaseSemantics::SValuePtr &dflt, BaseSemantics::RiscOperators *) ROSE_OVERRIDE
Read a register without side effects.
Base class for machine instructions.
boost::shared_ptr< class RegisterState > RegisterStatePtr
Shared-ownership pointer to RegisterState.
Type of values manipulated by the concrete domain.
boost::shared_ptr< MemoryState > MemoryStatePtr
Shared-ownership pointer to a memory state.
boost::shared_ptr< State > StatePtr
Shared-ownership pointer to a semantic state.
STL namespace.
boost::shared_ptr< class Dispatcher > DispatcherPtr
Shared-ownership pointer to Dispatcher.
virtual void hash(Combinatorics::Hasher &, BaseSemantics::RiscOperators *) const override
Hash the register state.
static Ptr instance()
Create a debugger object that isn't attached to any subordinate process.
Definition: Debugger.h:280
static MemoryStatePtr instance(const BaseSemantics::SValuePtr &addrProtoval, const BaseSemantics::SValuePtr &valProtoval, const Debugger::Ptr &process)
Construct a state attached to the specified process.
Main namespace for the ROSE library.
virtual bool merge(const BaseSemantics::MemoryStatePtr &other, BaseSemantics::RiscOperators *addrOps, BaseSemantics::RiscOperators *valOps) ROSE_OVERRIDE
Merge memory states for data flow analysis.
virtual void writeRegister(RegisterDescriptor, const BaseSemantics::SValuePtr &value, BaseSemantics::RiscOperators *) ROSE_OVERRIDE
Write a value to a register.
static DispatcherPtr instance(const BaseSemantics::RiscOperatorsPtr &ops)
Create a new dispatcher using the specified operators.
static RiscOperatorsPtr instance(const BaseSemantics::StatePtr &state)
Instantiate a new RiscOperators object.
Reference-counting intrusive smart pointer.
Definition: SharedPointer.h:68
boost::shared_ptr< class State > StatePtr
Shared-ownership pointer to State.
Debugger::Ptr process() const
Property: Process storing the state.
virtual BaseSemantics::RegisterStatePtr create(const BaseSemantics::SValuePtr &protoval, const RegisterDictionary *regdict) const ROSE_OVERRIDE
Virtual constructor.
boost::shared_ptr< Dispatcher > DispatcherPtr
Shared-ownership pointer to a semantics instruction dispatcher.
virtual void hash(Combinatorics::Hasher &, BaseSemantics::RiscOperators *addrOps, BaseSemantics::RiscOperators *valOps) const override
Calculate a hash for this memory state.
static RegisterStatePtr instance(const BaseSemantics::SValuePtr &protoval, const Debugger::Ptr &process)
Construct a state attached to the specified process.
const RegisterDictionary * registerDictionary() const
Property: Register dictionary.
Base classes for instruction semantics.
Definition: Dispatcher.h:18
virtual BaseSemantics::MemoryStatePtr create(const BaseSemantics::SValuePtr &addrProtoval, const BaseSemantics::SValuePtr &valProtoval) const ROSE_OVERRIDE
Virtual allocating constructor.
virtual void iprocSet(int key, BaseSemantics::InsnProcessor *) ROSE_OVERRIDE
Disabled in this class.
boost::shared_ptr< class MemoryState > MemoryStatePtr
Shared-ownership pointer to MemoryState.
Describes (part of) a physical CPU register.
ConcreteSemantics::SValuePtr SValuePtr
Shared-ownership pointer to SValue.
Base class for semantics machine states.
Definition: State.h:39
static RiscOperatorsPtr instance(const BaseSemantics::SValuePtr &protoval, const Debugger::Ptr &process)
Instantiate a new RiscOperators object.
Describes the specimen to be debugged.
Definition: Debugger.h:52
virtual int iprocKey(SgAsmInstruction *) const ROSE_OVERRIDE
Disabled in this class.
Functor that knows how to dispatch a single kind of instruction.
Definition: Dispatcher.h:25
virtual BaseSemantics::DispatcherPtr create(const BaseSemantics::RiscOperatorsPtr &ops, size_t addrWidth=0, const RegisterDictionary *regs=NULL) const ROSE_OVERRIDE
Virtual constructor.
static SValuePtr promote(const BaseSemantics::SValuePtr &v)
Promote a base value to a SymbolicSemantics value.
Base class for most instruction semantics RISC operators.
Definition: RiscOperators.h:48
Dispatches instructions through the RISC layer.
Definition: Dispatcher.h:44
const RegisterDictionary * regdict
Registers that are able to be stored by this state.
Definition: RegisterState.h:39
ConcreteSemantics::SValue SValue
Concrete values from the specimen.
virtual void zero() ROSE_OVERRIDE
Set all registers to the zero.
virtual BaseSemantics::RegisterStatePtr clone() const ROSE_OVERRIDE
Make a copy of this register state.
virtual BaseSemantics::MemoryStatePtr clone() const ROSE_OVERRIDE
Virtual allocating copy constructor.
virtual BaseSemantics::RiscOperatorsPtr create(const BaseSemantics::SValuePtr &protoval, const SmtSolverPtr &solver=SmtSolverPtr()) const ROSE_OVERRIDE
Virtual allocating constructor.
Defines registers available for a particular architecture.
Definition: Registers.h:37
static DispatcherPtr instance(const Debugger::Ptr &process, const BaseSemantics::SValuePtr &protoval=SValue::instance())
Create a new dispatcher using the specified process.
virtual bool merge(const BaseSemantics::RegisterStatePtr &other, BaseSemantics::RiscOperators *ops) ROSE_OVERRIDE
Merge register states for data flow analysis.
virtual void writeMemory(const BaseSemantics::SValuePtr &addr, const BaseSemantics::SValuePtr &value, BaseSemantics::RiscOperators *addrOps, BaseSemantics::RiscOperators *valOps) ROSE_OVERRIDE
Write a value to memory.
boost::shared_ptr< class RiscOperators > RiscOperatorsPtr
Shared-ownership pointer to RiscOperators.
static DispatcherPtr instance(const Debugger::Specimen &specimen, const BaseSemantics::SValuePtr &protoval=SValue::instance())
Create a new dispatcher using the specified executable specimen.
virtual BaseSemantics::SValuePtr readMemory(const BaseSemantics::SValuePtr &address, const BaseSemantics::SValuePtr &dflt, BaseSemantics::RiscOperators *addrOps, BaseSemantics::RiscOperators *valOps) ROSE_OVERRIDE
Read a value from memory.
static RiscOperatorsPtr promote(const BaseSemantics::RiscOperatorsPtr &x)
Run-time promotion of a base object to a NativeSemantics RiscOperators.
boost::shared_ptr< RegisterState > RegisterStatePtr
Shared-ownership pointer to a register state.
std::shared_ptr< class SmtSolver > SmtSolverPtr
Reference-counting pointer for SMT solvers.
Definition: SmtSolver.h:25
virtual void clear() ROSE_OVERRIDE
Removes stored values from the register state.
static MemoryStatePtr instance()
Construct a state not attached to any subordinate process.