// Metaprogram's revision differentiator structure // Copyright 2023 Nguyễn Gia Phong // // This file is distributed under the University of Illinois // Open Source License. See LICENSE.TXT for details. #ifndef KLEE_DIFFERENTIATOR_H #define KLEE_DIFFERENTIATOR_H #include "ExecutionState.h" #include "klee/Expr/ArrayCache.h" #include "klee/Expr/Expr.h" #include "klee/Expr/ExprVisitor.h" #include "klee/System/Time.h" #include #include #include #include namespace klee { struct ExprCmbnVisitor : ExprVisitor { ExprCmbnVisitor(char, ArrayCache&); Action visitExprPost(const Expr& e) override; /// Recorded output variables std::map, ref>> outVars; private: char revision; ArrayCache& arrayCache; }; struct Differentiator { /// Buffer of bytes typedef std::vector Bytes; /// argv stdin typedef std::pair, Bytes> TestInps; /// :rev (:var val) stdout typedef std::map, Bytes>> TestOuts; typedef std::map> Clusters; /// Extract revision number from given condition if any static std::pair extractPatchNumber(ref e); Differentiator(std::unique_ptr*, time::Span&, ArrayCache&); /// Extract differential test from concrete execution void extract(ExecutionState*, ExecutionState*, const std::vector&, const std::vector&); /// Compare with other exit states for possible differential tests void search(ExecutionState*); /// Log patch differentiation result void log(); /// Program revision numbers std::set revisions; /// Differentiated pairs std::map, TestOuts*> done; private: /// Program path for concrete execution. const char* prog; /// Exit states std::map> exits; /// Differential tests std::map tests; /// SMT solver "borrowed" from Executor std::unique_ptr* solver; /// SMT solving timeout time::Span solverTimeout; /// Symbolic memory array ArrayCache& arrayCache; /// Symbolic output renamers ExprCmbnVisitor visitorA, visitorB; }; } // namespace klee #endif // KLEE_DIFFERENTIATOR_H