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>
23namespace 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;
486 return errorIfReset_;
516 virtual size_t nLevels()
const {
return stack_.size(); }
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);
Extends std::map with methods that return optional values.
Memoizes calls to an SMT solver.
Found find(const ExprList &assertions)
Search for the specified assertions in the cache.
size_t size() const
Number of call records cached.
void insert(const Found &, Satisfiable, const ExprExprMap &evidence)
Insert a call record into the cache.
static Ptr instance()
Allocating constructor.
void clear()
Clear the entire cache as if it was just constructed.
ExprExprMap evidence(const Found &) const
Returns evidence of satisfiability.
S-Expr parsed from SMT solver text output.
RAII guard for solver stack.
bool isCommitted() const
Whether the guard is canceled.
~Transaction()
Destructor pops level unless canceled.
SmtSolver::Ptr solver() const
Solver being protected.
Transaction(const SmtSolver::Ptr &solver)
Constructor pushes level if solver is non-null.
void commit(bool b=true)
Cancel the popping during the destructor.
Interface to Satisfiability Modulo Theory (SMT) solvers.
const Stats & statistics() const
Property: Statistics for this solver.
std::map< std::string, bool > Availability
Solver availability map.
std::vector< SymbolicExpression::Ptr > ExprList
Ordered list of expressions.
const std::string & name() const
Property: Name of solver for debugging.
static void resetClassStatistics()
Resets statistics for the class.
virtual size_t nAssertions() const
Total number of assertions across all backtracking levels.
void requireLinkage(LinkMode) const
Assert required linkage.
void memoizer(const Memoizer::Ptr &)
Property: Memoizer.
SmtSolverPtr Ptr
Reference counting pointer for SMT solvers.
Memoizer::Ptr memoizer() const
Property: Memoizer.
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.
virtual void generateFile(std::ostream &, const ExprList &exprs, Definitions *)=0
Generates an input file for for the solver.
virtual ExprList assertions() const
All assertions.
virtual Satisfiable check()
Check satisfiability of current stack.
virtual size_t nAssertions(size_t backtrackingLevel)
Number of assertions at a specific backtracking level.
void resetStatistics()
Resets statistics for this solver.
virtual Ptr create() const =0
Virtual constructor.
Type
Type (sort) of expression.
virtual SymbolicExpression::Ptr evidenceForVariable(uint64_t varno)
Evidence of satisfiability for a bitvector variable.
Evidence evidenceByName() const
All evidence of satisfiability.
virtual size_t nLevels() const
Number of backtracking levels.
static void printSExpression(std::ostream &, const SExpr::Ptr &)
Print an S-Expr for debugging.
virtual void pop()
Pop a backtracking point.
static Stats classStatistics()
Property: Statistics across all solvers.
virtual std::vector< std::string > evidenceNames() const
Names of items for which satisfiability evidence exists.
static ExprList undoNormalization(const ExprList &, const SymbolicExpression::ExprExprHashMap &index)
Undo the normalizations that were performed earlier.
virtual Satisfiable satisfiable(const SymbolicExpression::Ptr &)
Determines if the specified expressions are all satisfiable, unsatisfiable, or unknown.
virtual SymbolicExpression::Ptr evidenceForAddress(uint64_t addr)
Evidence of satisfiability for a memory address.
static Ptr instance(const std::string &name)
Allocate a new solver by name.
static ExprList normalizeVariables(const ExprList &, SymbolicExpression::ExprExprHashMap &index)
Normalize expressions by renaming variables.
virtual void parseEvidence()
Parses evidence of satisfiability.
LinkMode
Bit flags to indicate the kind of solver interface.
@ LM_ANY
Any available mode.
@ LM_EXECUTABLE
An executable is available.
@ LM_LIBRARY
A runtime library is available.
@ LM_NONE
No available linkage.
static LinkMode bestLinkage(unsigned linkages)
Given a bit vector of linkages, return the best one.
Satisfiable
Satisfiability constants.
@ SAT_UNKNOWN
Could not be proved satisfiable or unsatisfiable.
@ SAT_YES
Satisfiable and evidence of satisfiability may be available.
@ SAT_NO
Provably unsatisfiable.
virtual Satisfiable checkLib()
Check satisfiability using a library API.
virtual void timeout(boost::chrono::duration< double > seconds)=0
Set the timeout for the solver.
void errorIfReset(bool b)
Property: Throw an exception if the solver is reset.
virtual Satisfiable checkTrivial()
Check whether the stack of assertions is trivially satisfiable.
LinkMode linkage() const
Property: How ROSE communicates with the solver.
virtual void insert(const ExprList &)
Insert assertions.
SmtSolver(const std::string &name, unsigned linkages)
Construct with name and linkage.
virtual void push()
Create a backtracking point.
virtual Satisfiable satisfiable(const ExprList &)
Determines if the specified expressions are all satisfiable, unsatisfiable, or unknown.
virtual void clearEvidence()
Clears evidence information.
virtual void findVariables(const SymbolicExpression::Ptr &, VariableSet &)
Return all variables that need declarations.
static void initDiagnostics()
Initialize diagnostic output facilities.
virtual Satisfiable triviallySatisfiable(const ExprList &exprs)
Determines if expressions are trivially satisfiable or unsatisfiable.
static Ptr bestAvailable()
Best available solver.
static Availability availability()
Availability of all known solvers.
virtual SymbolicExpression::Ptr evidenceForName(const std::string &) const
Evidence of satisfiability for a variable or memory address.
bool errorIfReset() const
Property: Throw an exception if the solver is reset.
ExprExprMap evidence() const
All evidence of satisfiability.
std::string outputText_
Additional output obtained by satisfiable().
virtual void insert(const SymbolicExpression::Ptr &)
Insert assertions.
Progress::Ptr progress() const
Progress reporting object.
virtual SymbolicExpression::Ptr evidenceForVariable(const SymbolicExpression::Ptr &var)
Evidence of satisfiability for a bitvector variable.
virtual const ExprList & assertions(size_t level) const
Assertions for a particular level.
virtual void selfTest()
Unit tests.
void name(const std::string &s)
Property: Name of solver for debugging.
std::set< uint64_t > Definitions
Free variables that have been defined.
virtual std::string getErrorMessage(int exitStatus)
Error message from running a solver executable.
std::pair< std::string, Type > StringTypePair
Maps expression nodes to term names.
std::vector< SExpr::Ptr > parseSExpressions(const std::string &)
Parse all SExprs from the specified string.
virtual void reset()
Reset solver state.
static Sawyer::Message::Facility mlog
Diagnostic facility.
void progress(const Progress::Ptr &progress)
Progress reporting object.
virtual Satisfiable checkExe()
Check satisfiability using text files and an executable.
Mapping from expression to expression.
Leaf node of an expression tree for instruction semantics.
Base class for all ROSE exceptions.
Holds a value or nothing.
Base class for reference counted objects.
Reference-counting intrusive smart pointer.
uint64_t Hash
Hash of symbolic expression.
std::shared_ptr< SmtSolver > SmtSolverPtr
Reference counting pointer.
Exceptions for all things SMT related.
ExprList sortedNormalized
Sorted and normalized assertions, regardless if found.
SymbolicExpression::ExprExprHashMap rewriteMap
Mapping from provided to sortedNormalized assertions.
ExprExprMap evidence
Normalized evidence if found and satisfiable.
Sawyer::Optional< Satisfiable > satisfiable
If found, whether satisfiable.
Exception for parse errors when reading SMT solver output.
double longestPrepareTime
Longest of times added to prepareTime.
size_t output_size
Amount of output produced by the SMT solver.
double evidenceTime
Total time in seconds to retrieve evidence of satisfiability.
double longestSolveTime
Longest of times added to the solveTime total.
size_t ncalls
Number of times satisfiable() was called.
size_t nSatisfied
Number of times the solver returned "satisified".
size_t nSolversDestroyed
Number of solvers destroyed.
size_t memoizationHits
Number of times memoization supplied a result.
double longestEvidenceTime
Longest of times added to evidenceTime.
double prepareTime
Total time in seconds spent creating assertions before solving.
size_t input_size
Bytes of input generated for satisfiable().
double solveTime
Total time in seconds spent in solver's solve function.
size_t nSolversCreated
Number of solvers created.
size_t nUnsatisfied
Number of times the solver returned "unsatisfied".
size_t nUnknown
Number of times the solver returned "unknown".