Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intergration with Cooddy #112

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
4 changes: 2 additions & 2 deletions include/klee/Core/TargetedExecutionReporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ ty min(ty left, ty right);
}; // namespace confidence

void reportFalsePositive(confidence::ty confidence,
const std::vector<ReachWithError> &errors,
const std::string &id, std::string whatToIncrease);
const ReachWithErrors &errors, const std::string &id,
std::string whatToIncrease);

} // namespace klee

Expand Down
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
Loading