Skip to content

Commit

Permalink
[squash] of Annotations branch
Browse files Browse the repository at this point in the history
  • Loading branch information
Lana243 authored and Columpio committed Oct 5, 2023
1 parent 37f0da6 commit c8b06fd
Show file tree
Hide file tree
Showing 61 changed files with 2,792 additions and 44 deletions.
7 changes: 5 additions & 2 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
[submodule "json"]
path = json
path = submodules/json
url = https://github.com/nlohmann/json.git
[submodule "optional"]
path = optional
path = submodules/optional
url = https://github.com/martinmoene/optional-lite.git
[submodule "submodules/pugixml"]
path = submodules/pugixml
url = https://github.com/zeux/pugixml.git
17 changes: 15 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -667,8 +667,21 @@ configure_file(${CMAKE_SOURCE_DIR}/include/klee/Config/CompileTimeInfo.h.cmin
################################################################################
include_directories("${CMAKE_BINARY_DIR}/include")
include_directories("${CMAKE_SOURCE_DIR}/include")
include_directories("${CMAKE_SOURCE_DIR}/json/include")
include_directories("${CMAKE_SOURCE_DIR}/optional/include")
include_directories("${CMAKE_SOURCE_DIR}/submodules/json/include")
include_directories("${CMAKE_SOURCE_DIR}/submodules/optional/include")


option(ENABLE_XML_ANNOTATION "Enable XML annotation" ON)

if (ENABLE_XML_ANNOTATION)
message(STATUS "XML annotation is enabled")
file(COPY "${CMAKE_SOURCE_DIR}/submodules/pugiconfig.hpp"
DESTINATION "${CMAKE_SOURCE_DIR}/submodules/pugixml/src")
include_directories("${CMAKE_SOURCE_DIR}/submodules/pugixml/src")
else()
message(STATUS "XML annotation is disabled")
set(ENABLE_XML_ANNOTATION 0)
endif()
# set(KLEE_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/include ${CMAKE_BINARY_DIR}/include)

################################################################################
Expand Down
3 changes: 3 additions & 0 deletions include/klee/Config/config.h.cmin
Original file line number Diff line number Diff line change
Expand Up @@ -122,4 +122,7 @@ macro for that. That would simplify the C++ code. */
/* Install directory for KLEE runtime */
#define KLEE_INSTALL_RUNTIME_DIR "@KLEE_INSTALL_RUNTIME_DIR@"

/* Enable XML annotation parser */
#define ENABLE_XML_ANNOTATION "@ENABLE_XML_ANNOTATION@"

#endif /* KLEE_CONFIG_H */
45 changes: 33 additions & 12 deletions include/klee/Core/Interpreter.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#define KLEE_INTERPRETER_H

#include "TerminationTypes.h"
#include "klee/Module/Annotation.h"

#include "klee/Module/SarifReport.h"

Expand All @@ -32,6 +33,7 @@ class BasicBlock;
class Function;
class LLVMContext;
class Module;
class Type;
class raw_ostream;
class raw_fd_ostream;
} // namespace llvm
Expand Down Expand Up @@ -66,6 +68,13 @@ using FLCtoOpcode = std::unordered_map<
std::unordered_map<
unsigned, std::unordered_map<unsigned, std::unordered_set<unsigned>>>>;

enum class MockStrategy {
None, // No mocks are generated
Naive, // For each function call new symbolic value is generated
Deterministic, // Each function is treated as uninterpreted function in SMT.
// Compatible with Z3 solver only
};

class Interpreter {
public:
enum class GuidanceKind {
Expand All @@ -82,21 +91,32 @@ class Interpreter {
std::string LibraryDir;
std::string EntryPoint;
std::string OptSuffix;
std::string MainCurrentName;
std::string MainNameAfterMock;
std::string AnnotationsFile;
bool Optimize;
bool Simplify;
bool CheckDivZero;
bool CheckOvershift;
bool AnnotateOnlyExternal;
bool WithFPRuntime;
bool WithPOSIXRuntime;

ModuleOptions(const std::string &_LibraryDir,
const std::string &_EntryPoint, const std::string &_OptSuffix,
bool _Optimize, bool _Simplify, bool _CheckDivZero,
bool _CheckOvershift, bool _WithFPRuntime,
const std::string &_MainCurrentName,
const std::string &_MainNameAfterMock,
const std::string &_AnnotationsFile, bool _Optimize,
bool _Simplify, bool _CheckDivZero, bool _CheckOvershift,
bool _AnnotateOnlyExternal, bool _WithFPRuntime,
bool _WithPOSIXRuntime)
: LibraryDir(_LibraryDir), EntryPoint(_EntryPoint),
OptSuffix(_OptSuffix), Optimize(_Optimize), Simplify(_Simplify),
CheckDivZero(_CheckDivZero), CheckOvershift(_CheckOvershift),
OptSuffix(_OptSuffix), MainCurrentName(_MainCurrentName),
MainNameAfterMock(_MainNameAfterMock),
AnnotationsFile(_AnnotationsFile), Optimize(_Optimize),
Simplify(_Simplify), CheckDivZero(_CheckDivZero),
CheckOvershift(_CheckOvershift),
AnnotateOnlyExternal(_AnnotateOnlyExternal),
WithFPRuntime(_WithFPRuntime), WithPOSIXRuntime(_WithPOSIXRuntime) {}
};

Expand All @@ -115,10 +135,11 @@ class Interpreter {
unsigned MakeConcreteSymbolic;
GuidanceKind Guidance;
nonstd::optional<SarifReport> Paths;
enum MockStrategy MockStrategy;

InterpreterOptions(nonstd::optional<SarifReport> Paths)
: MakeConcreteSymbolic(false), Guidance(GuidanceKind::NoGuidance),
Paths(std::move(Paths)) {}
Paths(std::move(Paths)), MockStrategy(MockStrategy::None) {}
};

protected:
Expand All @@ -141,13 +162,13 @@ class Interpreter {
/// module
/// \return The final module after it has been optimized, checks
/// inserted, and modified for interpretation.
virtual llvm::Module *
setModule(std::vector<std::unique_ptr<llvm::Module>> &userModules,
std::vector<std::unique_ptr<llvm::Module>> &libsModules,
const ModuleOptions &opts,
std::set<std::string> &&mainModuleFunctions,
std::set<std::string> &&mainModuleGlobals,
FLCtoOpcode &&origInstructions) = 0;
virtual llvm::Module *setModule(
std::vector<std::unique_ptr<llvm::Module>> &userModules,
std::vector<std::unique_ptr<llvm::Module>> &libsModules,
const ModuleOptions &opts, std::set<std::string> &&mainModuleFunctions,
std::set<std::string> &&mainModuleGlobals, FLCtoOpcode &&origInstructions,
const std::set<std::string> &ignoredExternals,
std::vector<std::pair<std::string, std::string>> redefinitions) = 0;

// supply a tree stream writer which the interpreter will use
// to record the concrete path (as a stream of '0' and '1' bytes).
Expand Down
71 changes: 71 additions & 0 deletions include/klee/Core/MockBuilder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#ifndef KLEE_MOCKBUILDER_H
#define KLEE_MOCKBUILDER_H

#include "klee/Core/Interpreter.h"
#include "klee/Module/Annotation.h"

#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/Module.h"

#include <set>
#include <string>

namespace klee {

class MockBuilder {
private:
const llvm::Module *userModule;
std::unique_ptr<llvm::Module> mockModule;
std::unique_ptr<llvm::IRBuilder<>> builder;

const Interpreter::ModuleOptions &opts;

std::set<std::string> ignoredExternals;
std::vector<std::pair<std::string, std::string>> redefinitions;

InterpreterHandler *interpreterHandler;

AnnotationsMap annotations;

void initMockModule();
void buildMockMain();
void buildExternalGlobalsDefinitions();
void buildExternalFunctionsDefinitions();
void
buildCallKleeMakeSymbolic(const std::string &kleeMakeSymbolicFunctionName,
llvm::Value *source, llvm::Type *type,
const std::string &symbolicName);

void buildAnnotationForExternalFunctionArgs(
llvm::Function *func,
const std::vector<std::vector<Statement::Ptr>> &statementsNotAllign);
void buildAnnotationForExternalFunctionReturn(
llvm::Function *func, const std::vector<Statement::Ptr> &statements);
void buildAnnotationForExternalFunctionProperties(
llvm::Function *func, const std::set<Statement::Property> &properties);

std::map<std::string, llvm::FunctionType *> getExternalFunctions();
std::map<std::string, llvm::Type *> getExternalGlobals();

std::pair<llvm::Value *, llvm::Value *>
goByOffset(llvm::Value *value, const std::vector<std::string> &offset);

public:
MockBuilder(const llvm::Module *initModule,
const Interpreter::ModuleOptions &opts,
const std::set<std::string> &ignoredExternals,
std::vector<std::pair<std::string, std::string>> &redefinitions,
InterpreterHandler *interpreterHandler);

std::unique_ptr<llvm::Module> build();
void buildAllocSource(llvm::Value *prev, llvm::Type *elemType,
const Statement::AllocSource *allocSourcePtr);
void buildFree(llvm::Value *elem, const Statement::Free *freePtr);
void processingValue(llvm::Value *prev, llvm::Type *elemType,
const Statement::AllocSource *allocSourcePtr,
const Statement::InitNull *initNullPtr);
};

} // namespace klee

#endif // KLEE_MOCKBUILDER_H
2 changes: 2 additions & 0 deletions include/klee/Expr/IndependentSet.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ class IndependentConstraintSet {

InnerSetUnion concretizedSets;

std::set<std::string> uninterpretedFunctions;

ref<const IndependentConstraintSet> addExpr(ref<Expr> e) const;
ref<const IndependentConstraintSet>
updateConcretization(const Assignment &delta,
Expand Down
8 changes: 8 additions & 0 deletions include/klee/Expr/SourceBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
#include "klee/Expr/SymbolicSource.h"
#include "klee/Module/KModule.h"

#include "llvm/IR/Function.h"

namespace klee {

class SourceBuilder {
Expand All @@ -28,6 +30,12 @@ class SourceBuilder {
static ref<SymbolicSource> value(const llvm::Value &_allocSite, int _index,
KModule *km);
static ref<SymbolicSource> irreproducible(const std::string &name);
static ref<SymbolicSource> mockNaive(const KModule *kModule,
const llvm::Function &kFunction,
unsigned version);
static ref<SymbolicSource>
mockDeterministic(const KModule *kModule, const llvm::Function &kFunction,
const std::vector<ref<Expr>> &args);
};

}; // namespace klee
Expand Down
58 changes: 57 additions & 1 deletion include/klee/Expr/SymbolicSource.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,12 @@ DISABLE_WARNING_POP

namespace klee {

class Expr;
class Array;
class Expr;
class ConstantExpr;
class KModule;
struct KFunction;

class SymbolicSource {
protected:
Expand All @@ -41,7 +43,9 @@ class SymbolicSource {
LazyInitializationSize,
Instruction,
Argument,
Irreproducible
Irreproducible,
MockNaive,
MockDeterministic
};

public:
Expand Down Expand Up @@ -361,6 +365,58 @@ class IrreproducibleSource : public SymbolicSource {
}
};

class MockSource : public SymbolicSource {
public:
const KModule *km;
const llvm::Function &function;
MockSource(const KModule *_km, const llvm::Function &_function)
: km(_km), function(_function) {}

static bool classof(const SymbolicSource *S) {
return S->getKind() == Kind::MockNaive ||
S->getKind() == Kind::MockDeterministic;
}
};

class MockNaiveSource : public MockSource {
public:
const unsigned version;

MockNaiveSource(const KModule *km, const llvm::Function &function,
unsigned _version)
: MockSource(km, function), version(_version) {}

Kind getKind() const override { return Kind::MockNaive; }
std::string getName() const override { return "mockNaive"; }

static bool classof(const SymbolicSource *S) {
return S->getKind() == Kind::MockNaive;
}

unsigned computeHash() override;

int internalCompare(const SymbolicSource &b) const override;
};

class MockDeterministicSource : public MockSource {
public:
const std::vector<ref<Expr>> args;

MockDeterministicSource(const KModule *_km, const llvm::Function &_function,
const std::vector<ref<Expr>> &_args);

Kind getKind() const override { return Kind::MockDeterministic; }
std::string getName() const override { return "mockDeterministic"; }

static bool classof(const SymbolicSource *S) {
return S->getKind() == Kind::MockDeterministic;
}

unsigned computeHash() override;

int internalCompare(const SymbolicSource &b) const override;
};

} // namespace klee

#endif /* KLEE_SYMBOLICSOURCE_H */
Loading

0 comments on commit c8b06fd

Please sign in to comment.