10#define DEBUG_TYPE "KModule"
21#include "klee/Support/Debug.h"
25#include "llvm/Bitcode/BitcodeWriter.h"
26#if LLVM_VERSION_CODE < LLVM_VERSION(8, 0)
27#include "llvm/IR/CallSite.h"
29#include "llvm/IR/DataLayout.h"
30#include "llvm/IR/IRBuilder.h"
31#include "llvm/IR/Instructions.h"
32#include "llvm/IR/LegacyPassManager.h"
33#include "llvm/IR/LLVMContext.h"
34#include "llvm/IR/Module.h"
35#include "llvm/IR/ValueSymbolTable.h"
36#include "llvm/IR/Verifier.h"
37#include "llvm/Linker/Linker.h"
38#include "llvm/Support/CommandLine.h"
39#include "llvm/Support/Path.h"
40#include "llvm/Support/raw_ostream.h"
41#include "llvm/Support/raw_os_ostream.h"
42#include "llvm/Transforms/Scalar.h"
43#if LLVM_VERSION_CODE >= LLVM_VERSION(8, 0)
44#include "llvm/Transforms/Scalar/Scalarizer.h"
46#include "llvm/Transforms/Utils/Cloning.h"
47#if LLVM_VERSION_CODE >= LLVM_VERSION(7, 0)
48#include "llvm/Transforms/Utils.h"
59 "These options affect the compile-time processing of the code.");
70 OutputSource(
"output-source",
71 cl::desc(
"Write the assembly for the final transformed source (default=true)"),
76 OutputModule(
"output-module",
77 cl::desc(
"Write the bitcode for the final transformed module"),
81 cl::opt<SwitchImplType>
82 SwitchType(
"switch-type", cl::desc(
"Select the implementation of switch (default=internal)"),
83 cl::values(clEnumValN(eSwitchTypeSimple,
"simple",
84 "lower to ordered branches"),
85 clEnumValN(eSwitchTypeLLVM,
"llvm",
87 clEnumValN(eSwitchTypeInternal,
"internal",
88 "execute switch internally")),
89 cl::init(eSwitchTypeInternal),
93 DebugPrintEscapingFunctions(
"debug-print-escaping-functions",
94 cl::desc(
"Print functions whose address is taken (default=false)"),
99 DontVerify(
"disable-verify",
100 cl::desc(
"Do not verify the module integrity (default=false)"),
104 OptimiseKLEECall(
"klee-call-optimisation",
105 cl::desc(
"Allow optimization of functions that "
106 "contain KLEE calls (default=true)"),
113extern void Optimize(Module *, llvm::ArrayRef<const char *> preservedFunctions);
120 assert(!gv->isDeclaration() && !gv->hasInternalLinkage() &&
121 "do not support old LLVM style constructor/destructor lists");
123 std::vector<Type *> nullary;
125 Function *fn = Function::Create(FunctionType::get(Type::getVoidTy(m->getContext()),
127 GlobalVariable::InternalLinkage,
130 BasicBlock *bb = BasicBlock::Create(m->getContext(),
"entry", fn);
131 llvm::IRBuilder<> Builder(bb);
136 auto arr = dyn_cast<ConstantArray>(gv->getInitializer());
138 for (
unsigned i=0; i<arr->getNumOperands(); i++) {
139 auto cs = cast<ConstantStruct>(arr->getOperand(i));
141#if LLVM_VERSION_CODE >= LLVM_VERSION(9, 0)
142 assert(cs->getNumOperands() == 3 &&
143 "unexpected element in ctor initializer list");
146 assert((cs->getNumOperands() == 2 || cs->getNumOperands() == 3) &&
147 "unexpected element in ctor initializer list");
149 auto fp = cs->getOperand(1);
150 if (!fp->isNullValue()) {
151 if (
auto ce = dyn_cast<llvm::ConstantExpr>(fp))
152 fp = ce->getOperand(0);
154 if (
auto f = dyn_cast<Function>(fp)) {
155 Builder.CreateCall(f);
157 assert(0 &&
"unable to get function pointer from ctor initializer list");
163 Builder.CreateRetVoid();
170 llvm::StringRef entryFunction) {
171 GlobalVariable *ctors = m->getNamedGlobal(
"llvm.global_ctors");
172 GlobalVariable *dtors = m->getNamedGlobal(
"llvm.global_dtors");
174 if (!ctors && !dtors)
177 Function *mainFn = m->getFunction(entryFunction);
179 klee_error(
"Entry function '%s' not found in module.",
180 entryFunction.str().c_str());
183 llvm::IRBuilder<> Builder(&*mainFn->begin()->begin());
189 for (Function::iterator it = mainFn->begin(), ie = mainFn->end(); it != ie;
191 if (isa<ReturnInst>(it->getTerminator())) {
192 llvm::IRBuilder<> Builder(it->getTerminator());
193 Builder.CreateCall(dtorStub);
199void KModule::addInternalFunction(
const char* functionName){
200 Function* internalFunction =
module->getFunction(functionName);
201 if (!internalFunction) {
203 "Failed to add internal function %s. Not found.", functionName));
206 KLEE_DEBUG(
klee_message(
"Added function %s.",functionName));
211 const std::string &entryPoint) {
212 auto numRemainingModules = modules.size();
214 modules.push_back(std::move(
module));
216 module = std::unique_ptr<llvm::Module>(
219 klee_error(
"Could not link KLEE files %s", error.c_str());
221 targetData = std::unique_ptr<llvm::DataLayout>(
new DataLayout(
module.get()));
224 return modules.size() != numRemainingModules;
232 legacy::PassManager pm;
241 pm.add(createScalarizerPass());
244 pm.add(createLowerAtomicPass());
254 llvm::ArrayRef<const char *> preservedFunctions) {
257 if (!OptimiseKLEECall) {
258 legacy::PassManager pm;
282 legacy::PassManager pm3;
283 pm3.add(createCFGSimplificationPass());
285 case eSwitchTypeInternal:
break;
287 case eSwitchTypeLLVM: pm3.add(createLowerSwitchPass());
break;
291 pm3.add(createScalarizerPass());
298 if (OutputSource || forceSourceOutput) {
299 std::unique_ptr<llvm::raw_fd_ostream> os(ih->
openOutputFile(
"assembly.ll"));
300 assert(os && !os->has_error() &&
"unable to open source output");
305 std::unique_ptr<llvm::raw_fd_ostream> f(ih->
openOutputFile(
"final.bc"));
306#if LLVM_VERSION_CODE >= LLVM_VERSION(7, 0)
307 WriteBitcodeToFile(*
module, *f);
309 WriteBitcodeToFile(
module.get(), *f);
315 infos = std::unique_ptr<InstructionInfoTable>(
318 std::vector<Function *> declarations;
320 for (
auto &Function : *
module) {
321 if (Function.isDeclaration()) {
322 declarations.push_back(&Function);
326 auto kf = std::unique_ptr<KFunction>(
new KFunction(&Function,
this));
328 for (
unsigned i=0; i<kf->numInstructions; ++i) {
333 functionMap.insert(std::make_pair(&Function, kf.get()));
344 for (
auto &declaration : declarations) {
350 llvm::errs() <<
"KLEE: escaping functions: [";
351 std::string delimiter =
"";
353 llvm::errs() << delimiter << Function->getName();
356 llvm::errs() <<
"]\n";
364 legacy::PassManager pm;
366 pm.add(createVerifierPass());
367 pm.add(operandTypeCheckPass);
374 klee_error(
"Unexpected instruction operand types detected");
381 return it->second.get();
390 auto kc = std::unique_ptr<KConstant>(
new KConstant(c,
id, ki));
391 constantMap.insert(std::make_pair(c, std::move(kc)));
407 std::map<Instruction*, unsigned> ®isterMap,
410 if (Instruction *inst = dyn_cast<Instruction>(v)) {
411 return registerMap[inst];
412 }
else if (Argument *a = dyn_cast<Argument>(v)) {
413 return a->getArgNo();
414 }
else if (isa<BasicBlock>(v) || isa<InlineAsm>(v) ||
415 isa<MetadataAsValue>(v)) {
418 assert(isa<Constant>(v));
419 Constant *c = cast<Constant>(v);
426 : function(_function),
427 numArgs(function->arg_size()),
429 trackCoverage(true) {
431 for (
auto &BasicBlock : *
function) {
438 std::map<Instruction*, unsigned> registerMap;
442 for (llvm::Function::iterator bbit =
function->begin(),
443 bbie =
function->end(); bbit != bbie; ++bbit) {
444 for (llvm::BasicBlock::iterator it = bbit->begin(), ie = bbit->end();
446 registerMap[&*it] = rnum++;
451 for (llvm::Function::iterator bbit =
function->begin(),
452 bbie =
function->end(); bbit != bbie; ++bbit) {
453 for (llvm::BasicBlock::iterator it = bbit->begin(), ie = bbit->end();
457 switch(it->getOpcode()) {
458 case Instruction::GetElementPtr:
459 case Instruction::InsertValue:
460 case Instruction::ExtractValue:
466 Instruction *inst = &*it;
468 ki->
dest = registerMap[inst];
470 if (isa<CallInst>(it) || isa<InvokeInst>(it)) {
471#if LLVM_VERSION_CODE >= LLVM_VERSION(8, 0)
472 const CallBase &cs = cast<CallBase>(*inst);
473 Value *val = cs.getCalledOperand();
475 const CallSite cs(inst);
476 Value *val = cs.getCalledValue();
478 unsigned numArgs = cs.arg_size();
481 for (
unsigned j=0; j<
numArgs; j++) {
482 Value *v = cs.getArgOperand(j);
486 unsigned numOperands = it->getNumOperands();
487 ki->
operands =
new int[numOperands];
488 for (
unsigned j=0; j<numOperands; j++) {
489 Value *v = it->getOperand(j);
static int getOperandNum(Value *v, std::map< Instruction *, unsigned > ®isterMap, KModule *km, KInstruction *ki)
static Function * getStubFunctionForCtorList(Module *m, GlobalVariable *gv, std::string name)
static void injectStaticConstructorsAndDestructors(Module *m, llvm::StringRef entryFunction)
virtual std::unique_ptr< llvm::raw_fd_ostream > openOutputFile(const std::string &filename)=0
KConstant(llvm::Constant *, unsigned, KInstruction *)
llvm::Constant * ct
Actual LLVM constant this represents.
unsigned getConstantID(llvm::Constant *c, KInstruction *ki)
Return an id for the given constant, creating a new one if necessary.
void optimiseAndPrepare(const Interpreter::ModuleOptions &opts, llvm::ArrayRef< const char * >)
Optimise and prepare module such that KLEE can execute it.
void addInternalFunction(const char *functionName)
KConstant * getKConstant(const llvm::Constant *c)
std::map< const llvm::Constant *, std::unique_ptr< KConstant > > constantMap
void instrument(const Interpreter::ModuleOptions &opts)
void manifest(InterpreterHandler *ih, bool forceSourceOutput)
bool link(std::vector< std::unique_ptr< llvm::Module > > &modules, const std::string &entryPoint)
std::set< const llvm::Function * > internalFunctions
std::unique_ptr< llvm::DataLayout > targetData
std::unique_ptr< InstructionInfoTable > infos
std::set< llvm::Function * > escapingFunctions
std::vector< std::unique_ptr< KFunction > > functions
std::vector< llvm::Constant * > constants
std::unique_ptr< llvm::Module > module
std::map< llvm::Function *, KFunction * > functionMap
Instruments every function that contains a KLEE function call as nonopt.
void klee_message(const char *msg,...) __attribute__((format(printf
std::unique_ptr< llvm::Module > linkModules(std::vector< std::unique_ptr< llvm::Module > > &modules, llvm::StringRef entryFunction, std::string &errorMsg)
bool functionEscapes(const llvm::Function *f)
cl::OptionCategory ModuleCat("Module-related options", "These options affect the compile-time processing of the code.")
void klee_error(const char *msg,...) __attribute__((format(printf
llvm::cl::OptionCategory ModuleCat
void void void klee_warning(const char *msg,...) __attribute__((format(printf
void Optimize(Module *, llvm::ArrayRef< const char * > preservedFunctions)
std::map< llvm::BasicBlock *, unsigned > basicBlockEntry
llvm::Function * function
KInstruction ** instructions
KFunction(llvm::Function *, KModule *)
const InstructionInfo * info
unsigned dest
Destination register index.