diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/klee/Internal/Module/KModule.h | 55 | ||||
-rw-r--r-- | include/klee/Internal/Support/ModuleUtil.h | 73 | ||||
-rw-r--r-- | include/klee/Interpreter.h | 14 |
3 files changed, 96 insertions, 46 deletions
diff --git a/include/klee/Internal/Module/KModule.h b/include/klee/Internal/Module/KModule.h index e8ded725..478e24d7 100644 --- a/include/klee/Internal/Module/KModule.h +++ b/include/klee/Internal/Module/KModule.h @@ -13,7 +13,10 @@ #include "klee/Config/Version.h" #include "klee/Interpreter.h" +#include "llvm/ADT/ArrayRef.h" + #include <map> +#include <memory> #include <set> #include <vector> @@ -50,12 +53,11 @@ namespace klee { /// "coverable" for statistics and search heuristics. bool trackCoverage; - private: - KFunction(const KFunction&); - KFunction &operator=(const KFunction&); - public: explicit KFunction(llvm::Function*, KModule *); + KFunction(const KFunction &) = delete; + KFunction &operator=(const KFunction &) = delete; + ~KFunction(); unsigned getArgRegister(unsigned index) { return index; } @@ -80,24 +82,24 @@ namespace klee { class KModule { public: - llvm::Module *module; - llvm::DataLayout *targetData; + std::unique_ptr<llvm::Module> module; + std::unique_ptr<llvm::DataLayout> targetData; // Our shadow versions of LLVM structures. - std::vector<KFunction*> functions; + std::vector<std::unique_ptr<KFunction>> functions; std::map<llvm::Function*, KFunction*> functionMap; // Functions which escape (may be called indirectly) // XXX change to KFunction std::set<llvm::Function*> escapingFunctions; - InstructionInfoTable *infos; + std::unique_ptr<InstructionInfoTable> infos; std::vector<llvm::Constant*> constants; - std::map<const llvm::Constant*, KConstant*> constantMap; + std::map<const llvm::Constant *, std::unique_ptr<KConstant>> constantMap; KConstant* getKConstant(const llvm::Constant *c); - Cell *constantTable; + std::unique_ptr<Cell[]> constantTable; // Functions which are part of KLEE runtime std::set<const llvm::Function*> internalFunctions; @@ -107,14 +109,37 @@ namespace klee { void addInternalFunction(const char* functionName); public: - KModule(llvm::Module *_module); - ~KModule(); + KModule() = default; - /// Initialize local data structures. + /// Optimise and prepare module such that KLEE can execute it // + void optimiseAndPrepare(const Interpreter::ModuleOptions &opts, + llvm::ArrayRef<const char *>); + + /// Manifest the generated module (e.g. assembly.ll, output.bc) and + /// prepares KModule + /// + /// @param ih + /// @param forceSourceOutput true if assembly.ll should be created + /// // FIXME: ihandler should not be here - void prepare(const Interpreter::ModuleOptions &opts, - InterpreterHandler *ihandler); + void manifest(InterpreterHandler *ih, bool forceSourceOutput); + + /// Link the provided modules together as one KLEE module. + /// + /// If the entry point is empty, all modules are linked together. + /// If the entry point is not empty, all modules are linked which resolve + /// the dependencies of the module containing entryPoint + /// + /// @param modules list of modules to be linked together + /// @param entryPoint name of the function which acts as the program's entry + /// point + /// @return true if at least one module has been linked in, false if nothing + /// changed + bool link(std::vector<std::unique_ptr<llvm::Module>> &modules, + const std::string &entryPoint); + + void instrument(const Interpreter::ModuleOptions &opts); /// Return an id for the given constant, creating a new one if necessary. unsigned getConstantID(llvm::Constant *c, KInstruction* ki); diff --git a/include/klee/Internal/Support/ModuleUtil.h b/include/klee/Internal/Support/ModuleUtil.h index 4c3243ce..8c819f40 100644 --- a/include/klee/Internal/Support/ModuleUtil.h +++ b/include/klee/Internal/Support/ModuleUtil.h @@ -13,8 +13,6 @@ #include "klee/Config/Version.h" #include "llvm/IR/Module.h" -#include "llvm/IR/Function.h" -#include "llvm/IR/LLVMContext.h" #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) #include "llvm/IR/CallSite.h" @@ -22,33 +20,58 @@ #include "llvm/Support/CallSite.h" #endif +#include <memory> #include <string> +#include <vector> namespace klee { - /// Load llvm module from a bitcode archive file. - llvm::Module *loadModule(llvm::LLVMContext &ctx, - const std::string &path, - std::string &errorMsg); - - /// Link a module with a specified bitcode archive. - llvm::Module *linkWithLibrary(llvm::Module *module, - const std::string &libraryName); - - /// Return the Function* target of a Call or Invoke instruction, or - /// null if it cannot be determined (should be only for indirect - /// calls, although complicated constant expressions might be - /// another possibility). - /// - /// If `moduleIsFullyLinked` is set to true it will be assumed that the - // module containing the `llvm::CallSite` is fully linked. This assumption - // allows resolution of functions that are marked as overridable. - llvm::Function *getDirectCallTarget(llvm::CallSite, bool moduleIsFullyLinked); - - /// Return true iff the given Function value is used in something - /// other than a direct call (or a constant expression that - /// terminates in a direct call). - bool functionEscapes(const llvm::Function *f); +/// Links all the modules together into one and returns it. +/// +/// All the modules which are used for resolving entities are freed, +/// all the remaining ones are preserved. +/// +/// @param modules List of modules to link together: if resolveOnly true, +/// everything is linked against the first entry. +/// @param entryFunction if set, missing functions of the module containing the +/// entry function will be solved. +/// @return final module or null in this case errorMsg is set +std::unique_ptr<llvm::Module> +linkModules(std::vector<std::unique_ptr<llvm::Module>> &modules, + llvm::StringRef entryFunction, std::string &errorMsg); + +/// Return the Function* target of a Call or Invoke instruction, or +/// null if it cannot be determined (should be only for indirect +/// calls, although complicated constant expressions might be +/// another possibility). +/// +/// If `moduleIsFullyLinked` is set to true it will be assumed that the +/// module containing the `llvm::CallSite` is fully linked. This assumption +/// allows resolution of functions that are marked as overridable. +llvm::Function *getDirectCallTarget(llvm::CallSite, bool moduleIsFullyLinked); + +/// Return true iff the given Function value is used in something +/// other than a direct call (or a constant expression that +/// terminates in a direct call). +bool functionEscapes(const llvm::Function *f); + +/// Loads the file libraryName and reads all possible modules out of it. +/// +/// Different file types are possible: +/// * .bc binary file +/// * .ll IR file +/// * .a archive containing .bc and .ll files +/// +/// @param libraryName library to read +/// @param modules contains extracted modules +/// @param errorMsg contains the error description in case the file could not be +/// loaded +/// @return true if successful otherwise false +bool loadFile(const std::string &libraryName, llvm::LLVMContext &context, + std::vector<std::unique_ptr<llvm::Module>> &modules, + std::string &errorMsg); + +void checkModule(llvm::Module *m); } #endif diff --git a/include/klee/Interpreter.h b/include/klee/Interpreter.h index 40f59ff1..4d8a580c 100644 --- a/include/klee/Interpreter.h +++ b/include/klee/Interpreter.h @@ -9,10 +9,11 @@ #ifndef KLEE_INTERPRETER_H #define KLEE_INTERPRETER_H -#include <vector> -#include <string> #include <map> +#include <memory> #include <set> +#include <string> +#include <vector> struct KTest; @@ -98,12 +99,13 @@ public: const InterpreterOptions &_interpreterOpts, InterpreterHandler *ih); - /// Register the module to be executed. - /// + /// Register the module to be executed. + /// \param modules A list of modules that should form the final + /// module /// \return The final module after it has been optimized, checks /// inserted, and modified for interpretation. - virtual const llvm::Module * - setModule(llvm::Module *module, + virtual llvm::Module * + setModule(std::vector<std::unique_ptr<llvm::Module>> &modules, const ModuleOptions &opts) = 0; // supply a tree stream writer which the interpreter will use |