1 #ifndef ROSE_BinaryAnalysis_SmtSolver_H
2 #define ROSE_BinaryAnalysis_SmtSolver_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
6 #ifndef __STDC_FORMAT_MACROS
7 #define __STDC_FORMAT_MACROS
10 #include <Rose/BinaryAnalysis/SymbolicExpression.h>
11 #include <Rose/Exception.h>
12 #include <Rose/Progress.h>
14 #include <boost/chrono.hpp>
15 #include <boost/lexical_cast.hpp>
16 #include <boost/noncopyable.hpp>
17 #include <boost/serialization/access.hpp>
18 #include <boost/thread/mutex.hpp>
20 #include <unordered_map>
23 namespace BinaryAnalysis {
42 using ExprList = std::vector<SymbolicExpression::Ptr>;
63 enum Type { NO_TYPE, BOOLEAN, BIT_VECTOR, MEM_STATE };
80 ParseError(
const std::pair<size_t /*line*/, size_t /*col*/> &loc,
const std::string &mesg)
81 :
Exception(
"input line " + boost::lexical_cast<std::string>(loc.first+1) +
82 " column " + boost::lexical_cast<std::string>(loc.second+1) +
": " + mesg) {}
114 void print(std::ostream&,
const std::string &prefix =
"")
const;
138 : solver_(solver), committed_(false) {
140 nLevels_ = solver->nLevels();
149 if (solver_ && !committed_) {
150 ASSERT_require2(solver_->nLevels() > nLevels_,
"something popped this transaction already");
151 while (solver_->nLevels() > nLevels_) {
152 if (solver_->nLevels() > 1) {
187 explicit SExpr(
const std::string &content): content_(content) {}
188 std::string content_;
189 std::vector<Ptr> children_;
191 static Ptr instance(
const std::string &content);
192 static Ptr instance(
size_t);
195 const std::string name()
const {
return content_; }
196 const std::vector<Ptr>& children()
const {
return children_; }
197 std::vector<Ptr>& children() {
return children_; }
198 void append(
const std::vector<Ptr>&);
199 void print(std::ostream&)
const;
202 using SExprTypePair = std::pair<SExpr::Ptr, Type>;
241 explicit operator bool()
const {
247 using ExprExpr = std::pair<SymbolicExpression::Ptr, SymbolicExpression::Ptr>;
257 using Map = std::multimap<SymbolicExpression::Hash, Record>;
260 mutable SAWYER_THREAD_TRAITS::Mutex mutex_;
308 std::vector<ExprList> stack_;
314 std::vector<SExpr::Ptr> parsedOutput_;
321 static boost::mutex classStatsMutex;
322 static Stats classStats;
330 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
331 friend class boost::serialization::access;
334 void serialize(S &s,
const unsigned ) {
335 s & BOOST_SERIALIZATION_NVP(name_);
336 s & BOOST_SERIALIZATION_NVP(stack_);
360 : name_(name), errorIfReset_(false), linkage_(
LM_NONE) {
404 const std::string&
name()
const {
return name_; }
405 void name(
const std::string &s) { name_ = s; }
439 virtual void timeout(boost::chrono::duration<double> seconds) = 0;
477 virtual void reset();
486 return errorIfReset_;
516 virtual size_t nLevels()
const {
return stack_.size(); }
521 virtual size_t nAssertions(
size_t backtrackingLevel);
582 virtual SymbolicExpression::Ptr
evidenceForName(
const std::string&)
const;
619 ASSERT_require(ln && ln->isVariable2());
624 snprintf(buf,
sizeof buf,
"v%" PRIu64, varno);
713 virtual std::string
getCommand(
const std::string &config_name) = 0;
753 void init(
unsigned linkages);
756 std::ostream& operator<<(std::ostream&,
const SmtSolver::SExpr&);
virtual void push()
Create a backtracking point.
SmtSolverPtr Ptr
Reference counting pointer for SMT solvers.
virtual Satisfiable triviallySatisfiable(const ExprList &exprs)
Determines if expressions are trivially satisfiable or unsatisfiable.
bool isCommitted() const
Whether the guard is canceled.
ExprExprMap evidence() const
All evidence of satisfiability.
Sawyer::Optional< Satisfiable > satisfiable
If found, whether satisfiable.
virtual void findVariables(const SymbolicExpression::Ptr &, VariableSet &)
Return all variables that need declarations.
virtual void insert(const SymbolicExpression::Ptr &)
Insert assertions.
Memoizer::Ptr memoizer() const
Property: Memoizer.
S-Expr parsed from SMT solver text output.
virtual Satisfiable checkLib()
Check satisfiability using a library API.
double longestPrepareTime
Longest of times added to prepareTime.
virtual void clearEvidence()
Clears evidence information.
Satisfiable and evidence of satisfiability may be available.
Sawyer::SharedPointer< Memoizer > Ptr
Reference counting pointer.
size_t nUnsatisfied
Number of times the solver returned "unsatisfied".
static void printSExpression(std::ostream &, const SExpr::Ptr &)
Print an S-Expr for debugging.
double longestEvidenceTime
Longest of times added to evidenceTime.
size_t ncalls
Number of times satisfiable() was called.
void requireLinkage(LinkMode) const
Assert required linkage.
Memoizes calls to an SMT solver.
virtual void timeout(boost::chrono::duration< double > seconds)=0
Set the timeout for the solver.
void clear()
Clear the entire cache as if it was just constructed.
virtual void reset()
Reset solver state.
ExprExprMap evidence
Normalized evidence if found and satisfiable.
std::string outputText_
Additional output obtained by satisfiable().
Mapping from expression to expression.
static Ptr instance()
Allocating constructor.
const std::string & name() const
Property: Name of solver for debugging.
LinkMode
Bit flags to indicate the kind of solver interface.
Main namespace for the ROSE library.
size_t nSolversCreated
Number of solvers created.
static Availability availability()
Availability of all known solvers.
Satisfiable
Satisfiability constants.
virtual SymbolicExpression::Ptr evidenceForName(const std::string &) const
Evidence of satisfiability for a variable or memory address.
Reference-counting intrusive smart pointer.
virtual Satisfiable check()
Check satisfiability of current stack.
void resetStatistics()
Resets statistics for this solver.
size_t nSatisfied
Number of times the solver returned "satisified".
double prepareTime
Total time in seconds spent creating assertions before solving.
bool errorIfReset() const
Property: Throw an exception if the solver is reset.
virtual size_t nAssertions() const
Total number of assertions across all backtracking levels.
virtual size_t nLevels() const
Number of backtracking levels.
Exceptions for all things SMT related.
static void resetClassStatistics()
Resets statistics for the class.
Progress::Ptr progress() const
Progress reporting object.
virtual Ptr create() const =0
Virtual constructor.
std::set< uint64_t > Definitions
Free variables that have been defined.
Sawyer::Container::Map< SymbolicExpression::Ptr, SymbolicExpression::Ptr > ExprExprMap
Maps one symbolic expression to another.
static Ptr bestAvailable()
Best available solver.
static Ptr instance(const std::string &name)
Allocate a new solver by name.
void name(const std::string &s)
Property: Name of solver for debugging.
void errorIfReset(bool b)
Property: Throw an exception if the solver is reset.
ExprExprMap evidence(const Found &) const
Returns evidence of satisfiability.
static void initDiagnostics()
Initialize diagnostic output facilities.
std::map< std::string, bool > Availability
Solver availability map.
virtual Satisfiable checkExe()
Check satisfiability using text files and an executable.
~Transaction()
Destructor pops level unless canceled.
virtual SymbolicExpression::Ptr evidenceForVariable(const SymbolicExpression::Ptr &var)
Evidence of satisfiability for a bitvector variable.
double longestSolveTime
Longest of times added to the solveTime total.
Exception for parse errors when reading SMT solver output.
Found find(const ExprList &assertions)
Search for the specified assertions in the cache.
SmtSolver(const std::string &name, unsigned linkages)
Construct with name and linkage.
size_t size() const
Number of call records cached.
virtual SymbolicExpression::Ptr evidenceForAddress(uint64_t addr)
Evidence of satisfiability for a memory address.
void commit(bool b=true)
Cancel the popping during the destructor.
Extends std::map with methods that return optional values.
uint64_t Hash
Hash of symbolic expression.
Transaction(const SmtSolver::Ptr &solver)
Constructor pushes level if solver is non-null.
virtual SymbolicExpression::Ptr evidenceForVariable(uint64_t varno)
Evidence of satisfiability for a bitvector variable.
virtual void selfTest()
Unit tests.
const Stats & statistics() const
Property: Statistics for this solver.
virtual void generateFile(std::ostream &, const ExprList &exprs, Definitions *)=0
Generates an input file for for the solver.
Evidence evidenceByName() const
All evidence of satisfiability.
virtual Satisfiable checkTrivial()
Check whether the stack of assertions is trivially satisfiable.
An executable is available.
virtual ExprList assertions() const
All assertions.
Base class for reference counted objects.
A runtime library is available.
virtual void pop()
Pop a backtracking point.
Type
Type (sort) of expression.
size_t nSolversDestroyed
Number of solvers destroyed.
Could not be proved satisfiable or unsatisfiable.
SmtSolver::Ptr solver() const
Solver being protected.
std::shared_ptr< SmtSolver > SmtSolverPtr
Reference counting pointer.
Leaf node of an expression tree for instruction semantics.
std::vector< SymbolicExpression::Ptr > ExprList
Ordered list of expressions.
void insert(const Found &, Satisfiable, const ExprExprMap &evidence)
Insert a call record into the cache.
virtual Satisfiable satisfiable(const SymbolicExpression::Ptr &)
Determines if the specified expressions are all satisfiable, unsatisfiable, or unknown.
double evidenceTime
Total time in seconds to retrieve evidence of satisfiability.
static ExprList undoNormalization(const ExprList &, const SymbolicExpression::ExprExprHashMap &index)
Undo the normalizations that were performed earlier.
double solveTime
Total time in seconds spent in solver's solve function.
virtual std::string getCommand(const std::string &config_name)=0
Given the name of a configuration file, return the command that is needed to run the solver...
ExprList sortedNormalized
Sorted and normalized assertions, regardless if found.
Interface to Satisfiability Modulo Theory (SMT) solvers.
size_t input_size
Bytes of input generated for satisfiable().
Base class for all ROSE exceptions.
static ExprList normalizeVariables(const ExprList &, SymbolicExpression::ExprExprHashMap &index)
Normalize expressions by renaming variables.
virtual void parseEvidence()
Parses evidence of satisfiability.
std::vector< SExpr::Ptr > parseSExpressions(const std::string &)
Parse all SExprs from the specified string.
std::pair< std::string, Type > StringTypePair
Maps expression nodes to term names.
static Stats classStatistics()
Property: Statistics across all solvers.
static LinkMode bestLinkage(unsigned linkages)
Given a bit vector of linkages, return the best one.
SymbolicExpression::ExprExprHashMap rewriteMap
Mapping from provided to sortedNormalized assertions.
static Sawyer::Message::Facility mlog
Diagnostic facility.
virtual std::vector< std::string > evidenceNames() const
Names of items for which satisfiability evidence exists.
size_t memoizationHits
Number of times memoization supplied a result.
LinkMode linkage() const
Property: How ROSE communicates with the solver.
size_t nUnknown
Number of times the solver returned "unknown".
virtual std::string getErrorMessage(int exitStatus)
Error message from running a solver executable.
RAII guard for solver stack.
size_t output_size
Amount of output produced by the SMT solver.