void InstructionReplace::insertStores(llvm::Module& M) { for(llvm::Module::iterator F = M.begin(), ME = M.end(); F != ME; ++F) { //if(!F->getFnAttributes().hasAttribute(Attributes::AttrVal::MaskedCopy)) { continue; } llvm::Function* Fun = maskedfn[F]; vector<Value*> outputshares; ReturnInst* tbd = NULL; auto arg = Fun->arg_begin(); for(unsigned int i = 0; i <= MaskingOrder; i++) { ++arg; } for(unsigned int i = 0; i <= MaskingOrder; i++) { outputshares.push_back(arg++); } for(llvm::Function::iterator BB = Fun->begin(), FE = Fun->end(); BB != FE; ++BB) { for( llvm::BasicBlock::iterator i = BB->begin(); i != BB->end(); i++) { if(tbd != NULL) {tbd->eraseFromParent(); tbd = NULL;} if(!isa<ReturnInst>(i)) {continue;} ReturnInst* ri = cast<ReturnInst>(i); IRBuilder<> ib = llvm::IRBuilder<>(BB->getContext()); ib.SetInsertPoint(i); vector<Value*> shares = MaskValue(ri->getReturnValue(), ri); for(unsigned int i = 0; i <= MaskingOrder; i++) { ib.CreateStore(shares[i], outputshares[i]); } ib.CreateRetVoid(); tbd = ri; } } if(tbd != NULL) {tbd->eraseFromParent(); tbd = NULL;} } }
void InstructionReplace::phase1(llvm::Module& M) { for(llvm::Module::iterator F = M.begin(), ME = M.end(); F != ME; ++F) { for(llvm::Function::iterator BB = F->begin(), FE = F->end(); BB != FE; ++BB) { TaggedData& td = getAnalysis<TaggedData>(*F); if(!td.functionMarked(F)) {continue;} cerr << "phase1 " << F->getName().str() << endl; CalcDFG& cd = getAnalysis<CalcDFG>(*F); cd.setAsTransformed(F.getNodePtrUnchecked()); for( llvm::BasicBlock::iterator i = BB->begin(); i != BB->end(); i++) { if(isa<llvm::DbgInfoIntrinsic>(i)) {continue;} if(!cd.shouldBeProtected(i)) { continue; } NoCryptoFA::InstructionMetadata* md = NoCryptoFA::known[i]; if(md->origin != NoCryptoFA::InstructionMetadata::ORIGINAL_PROGRAM && md->origin != NoCryptoFA::InstructionMetadata::MASKED_FUNCTION) { continue; } MaskingVisitor mv; if(mv.visit(i)) { deletionqueue.insert(i); md->hasBeenMasked = true; } } } } }
void InstructionReplace::cloneFunctions(llvm::Module& M) { for(llvm::Module::iterator F = M.begin(), ME = M.end(); F != ME; ++F) { //if(!F->getFnAttributes().hasAttribute(Attributes::AttrVal::MaskedCopy)) { continue; } cerr << "Masking " << F->getName().str(); assert(F->arg_size() == 1); Type* rettype = F->getReturnType(); auto args = F->arg_begin(); Argument* a1 = args++; Type* paramtype = a1->getType(); assert(isa<IntegerType>(rettype)); assert(isa<IntegerType>(paramtype)); stringstream ss(""); ss << "__masked__" << F->getName().str(); llvm::LLVMContext& Ctx = M.getContext(); llvm::Constant* FunSym; std::vector<Type*> paramtypes; for(unsigned int i = 0; i <= MaskingOrder; i++) { paramtypes.push_back(paramtype); } //TODO riducibile? for(unsigned int i = 0; i <= MaskingOrder; i++) { paramtypes.push_back(rettype->getPointerTo()); } llvm::FunctionType* ftype = llvm::FunctionType::get(llvm::Type::getVoidTy(Ctx), llvm::ArrayRef<Type*>(paramtypes), false); FunSym = M.getOrInsertFunction(ss.str(), ftype); llvm::Function* newF = llvm::cast<llvm::Function>(FunSym); maskedfn[F] = newF; SmallVector<llvm::ReturnInst*, 4> rets; ValueToValueMapTy vmap; llvm::BasicBlock* Entry = llvm::BasicBlock::Create(Ctx, "entry", newF); llvm::IRBuilder<> ib_entry = llvm::IRBuilder<>(Entry->getContext()); ib_entry.SetInsertPoint(Entry); NoCryptoFA::InstructionMetadata* md = new NoCryptoFA::InstructionMetadata(); md->hasBeenMasked = true; auto arg = newF->arg_begin(); for(unsigned int i = 0; i <= MaskingOrder; i++) { md->MaskedValues.push_back(arg++); } Value* fakevalue = ib_entry.CreateAdd(md->MaskedValues[0], md->MaskedValues[1]); md->my_instruction = cast<Instruction>(fakevalue); NoCryptoFA::known[ md->my_instruction] = md; deletionqueue.insert(md->my_instruction); vmap.insert(std::make_pair(a1, fakevalue)); CloneFunctionInto(newF, F, vmap, true, rets); ib_entry.CreateBr(cast<BasicBlock>(vmap[&F->getEntryBlock()])); /* AttrBuilder toremove; //toremove.addAttribute(Attributes::AttrVal::MaskedCopy); toremove.addAttribute(Attributes::AttrVal::ZExt); toremove.addAttribute(Attributes::AttrVal::SExt); toremove.addAttribute(Attributes::AttrVal::NoAlias); toremove.addAttribute(Attributes::AttrVal::NoCapture); toremove.addAttribute(Attributes::AttrVal::StructRet); toremove.addAttribute(Attributes::AttrVal::ByVal); toremove.addAttribute(Attributes::AttrVal::Nest); newF->removeFnAttr(Attributes::get(Ctx, toremove)); newF->removeAttribute(0, Attributes::get(Ctx, toremove)); //Thr..ehm,Zero is a magic number! Toglie gli attributi zeroext e simili dal valore di ritorno. */ TaggedData& td = getAnalysis<TaggedData>(*F); //td.markFunction(newF); //setFullyMasked(newF); } }
bool AddressTakenAnalysis::runOnModule(llvm::Module& M) { for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI){ if(isAddressTaken(FI)) { addressTakenFunctions.insert(FI); } } return false; }
bool TimeProfiler::runOnModule(llvm::Module &M) { Function *Main = M.getFunction("main"); if (Main == 0) { errs() << "WARNING: cannot insert edge profiling into a module" << " with no main function!\n"; return false; // No main, no instrumentation! } std::vector<CallInst*> Traped; Function* wtime = NULL; for(auto F = M.begin(), E = M.end(); F!=E; ++F){ if((*F).getName() == "mpi_wtime_") wtime = &*F; for(auto I = inst_begin(*F), IE = inst_end(*F); I!=IE; ++I){ CallInst* CI = dyn_cast<CallInst>(&*I); if(CI == NULL) continue; Value* CV = const_cast<CallInst*>(CI)->getCalledValue(); Function* func = dyn_cast<Function>(castoff(CV)); if(func == NULL) errs()<<"No func!\n"; StringRef str = func->getName(); if(str.startswith("mpi_")) { if(str.startswith("mpi_init_")||str.startswith("mpi_comm_rank_")||str.startswith("mpi_comm_size_")) continue; Traped.push_back(CI); } } } IRBuilder<> Builder(M.getContext()); Type* DoubleTy = Type::getDoubleTy(M.getContext()); Type*ATy = ArrayType::get(DoubleTy, Traped.size()); GlobalVariable* Counters = new GlobalVariable(M, ATy, false, GlobalVariable::InternalLinkage, Constant::getNullValue(ATy), "TimeCounters"); unsigned I=0; for(auto P : Traped){ ArrayRef<Value*> args; CallInst* callTime = CallInst::Create(wtime, args, "", P); IncrementTimeCounter(callTime, wtime, I++, Counters, Builder, P); } InsertPredProfilingInitCall(Main, "llvm_start_time_profiling", Counters); return true; }
bool _removeUnusedFromModule() { using namespace llvm; // do not slice away these functions no matter what // FIXME do it a vector and fill it dynamically according // to what is the setup (like for sv-comp or general..) const char *keep[] = {options.dgOptions.entryFunction.c_str(), "klee_assume", nullptr}; // when erasing while iterating the slicer crashes // so set the to be erased values into container // and then erase them std::set<Function *> funs; std::set<GlobalVariable *> globals; std::set<GlobalAlias *> aliases; for (auto I = M->begin(), E = M->end(); I != E; ++I) { Function *func = &*I; if (array_match(func->getName(), keep)) continue; // if the function is unused or we haven't constructed it // at all in dependence graph, we can remove it // (it may have some uses though - like when one // unused func calls the other unused func if (func->hasNUses(0)) funs.insert(func); } for (auto I = M->global_begin(), E = M->global_end(); I != E; ++I) { GlobalVariable *gv = &*I; if (gv->hasNUses(0)) globals.insert(gv); } for (GlobalAlias& ga : M->getAliasList()) { if (ga.hasNUses(0)) aliases.insert(&ga); } for (Function *f : funs) f->eraseFromParent(); for (GlobalVariable *gv : globals) gv->eraseFromParent(); for (GlobalAlias *ga : aliases) ga->eraseFromParent(); return (!funs.empty() || !globals.empty() || !aliases.empty()); }
/*! * Invoke llvm passes to modify module */ void SymbolTableInfo::prePassSchedule(llvm::Module& module) { /// BreakConstantGEPs Pass BreakConstantGEPs* p1 = new BreakConstantGEPs(); p1->runOnModule(module); /// MergeFunctionRets Pass UnifyFunctionExitNodes* p2 = new UnifyFunctionExitNodes(); for (Module::iterator it = module.begin(), eit = module.end(); it != eit; ++it) { Function& fun = *it; if(fun.isDeclaration()) continue; p2->runOnFunction(fun); } }
void InstructionReplace::phase2(llvm::Module& M) { for(llvm::Module::iterator F = M.begin(), ME = M.end(); F != ME; ++F) { for(llvm::Function::iterator BB = F->begin(), FE = F->end(); BB != FE; ++BB) { TaggedData& td = getAnalysis<TaggedData>(*F); if(!td.functionMarked(F)) {continue;} for( llvm::BasicBlock::iterator i = BB->begin(); i != BB->end(); i++) { NoCryptoFA::InstructionMetadata* md = NoCryptoFA::known[i]; if(!md->hasBeenMasked) { continue; } for(Instruction::use_iterator u = i->use_begin(); u != i->use_end(); ++u) { Instruction* utilizzatore = cast<Instruction>(u.getUse().getUser()); NoCryptoFA::InstructionMetadata* usemd = NoCryptoFA::known[utilizzatore]; if(usemd->MaskedValues.empty()) { Unmask(i); } } } } } }
// based on llc code, University of Illinois Open Source License static void codegenModule(llvm::TargetMachine &Target, llvm::Module& m, llvm::raw_fd_ostream& out, llvm::TargetMachine::CodeGenFileType fileType) { using namespace llvm; // Build up all of the passes that we want to do to the module. FunctionPassManager Passes(&m); #if LDC_LLVM_VER >= 302 if (const DataLayout *DL = Target.getDataLayout()) Passes.add(new DataLayout(*DL)); else Passes.add(new DataLayout(&m)); #else if (const TargetData *TD = Target.getTargetData()) Passes.add(new TargetData(*TD)); else Passes.add(new TargetData(&m)); #endif #if LDC_LLVM_VER >= 303 Target.addAnalysisPasses(Passes); #endif llvm::formatted_raw_ostream fout(out); if (Target.addPassesToEmitFile(Passes, fout, fileType, codeGenOptLevel())) llvm_unreachable("no support for asm output"); Passes.doInitialization(); // Run our queue of passes all at once now, efficiently. for (llvm::Module::iterator I = m.begin(), E = m.end(); I != E; ++I) if (!I->isDeclaration()) Passes.run(*I); Passes.doFinalization(); }
/*! * This method identify which is value sym and which is object sym */ void SymbolTableInfo::buildMemModel(llvm::Module& module) { analysisUtil::increaseStackSize(); prePassSchedule(module); mod = &module; maxFieldLimit = maxFieldNumLimit; // Object #0 is black hole the object that may point to any object assert(totalSymNum == BlackHole && "Something changed!"); symTyMap.insert(std::make_pair(totalSymNum++, BlackHole)); createBlkOrConstantObj(BlackHole); // Object #1 always represents the constant assert(totalSymNum == ConstantObj && "Something changed!"); symTyMap.insert(std::make_pair(totalSymNum++, ConstantObj)); createBlkOrConstantObj(ConstantObj); // Pointer #2 always represents the pointer points-to black hole. assert(totalSymNum == BlkPtr && "Something changed!"); symTyMap.insert(std::make_pair(totalSymNum++, BlkPtr)); // Pointer #3 always represents the null pointer. assert(totalSymNum == NullPtr && "Something changed!"); symTyMap.insert(std::make_pair(totalSymNum, NullPtr)); // Add symbols for all the globals . for (Module::global_iterator I = module.global_begin(), E = module.global_end(); I != E; ++I) { collectSym(&*I); } // Add symbols for all the global aliases for (Module::alias_iterator I = module.alias_begin(), E = module.alias_end(); I != E; I++) { collectSym(&*I); } // Add symbols for all of the functions and the instructions in them. for (Module::iterator F = module.begin(), E = module.end(); F != E; ++F) { collectSym(&*F); collectRet(&*F); if (F->getFunctionType()->isVarArg()) collectVararg(&*F); // Add symbols for all formal parameters. for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I) { collectSym(&*I); } // collect and create symbols inside the function body for (inst_iterator II = inst_begin(&*F), E = inst_end(&*F); II != E; ++II) { const Instruction *inst = &*II; collectSym(inst); // initialization for some special instructions //{@ if (const StoreInst *st = dyn_cast<StoreInst>(inst)) { collectSym(st->getPointerOperand()); collectSym(st->getValueOperand()); } else if (const LoadInst *ld = dyn_cast<LoadInst>(inst)) { collectSym(ld->getPointerOperand()); } else if (const PHINode *phi = dyn_cast<PHINode>(inst)) { for (u32_t i = 0; i < phi->getNumIncomingValues(); ++i) { collectSym(phi->getIncomingValue(i)); } } else if (const GetElementPtrInst *gep = dyn_cast<GetElementPtrInst>( inst)) { collectSym(gep->getPointerOperand()); } else if (const SelectInst *sel = dyn_cast<SelectInst>(inst)) { collectSym(sel->getTrueValue()); collectSym(sel->getFalseValue()); } else if (const CastInst *cast = dyn_cast<CastInst>(inst)) { collectSym(cast->getOperand(0)); } else if (const ReturnInst *ret = dyn_cast<ReturnInst>(inst)) { if(ret->getReturnValue()) collectSym(ret->getReturnValue()); } else if (isCallSite(inst) && isInstrinsicDbgInst(inst)==false) { CallSite cs = analysisUtil::getLLVMCallSite(inst); callSiteSet.insert(cs); for (CallSite::arg_iterator it = cs.arg_begin(); it != cs.arg_end(); ++it) { collectSym(*it); } // Calls to inline asm need to be added as well because the callee isn't // referenced anywhere else. const Value *Callee = cs.getCalledValue(); collectSym(Callee); //TODO handle inlineAsm ///if (isa<InlineAsm>(Callee)) } //@} } } }
/// ValueEnumerator - Enumerate module-level information. ValueEnumerator::ValueEnumerator(const llvm::Module &M, bool ShouldPreserveUseListOrder) : HasMDString(false), HasDILocation(false), ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) { assert(!ShouldPreserveUseListOrder && "not supported UseListOrders = predictUseListOrder(M)"); // Enumerate the global variables. for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) EnumerateValue(I); // Enumerate the functions. for (llvm::Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) { EnumerateValue(I); EnumerateAttributes(cast<Function>(I)->getAttributes()); } // Enumerate the aliases. for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) EnumerateValue(I); // Remember what is the cutoff between globalvalue's and other constants. unsigned FirstConstant = Values.size(); // Enumerate the global variable initializers. for (llvm::Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I) if (I->hasInitializer()) EnumerateValue(I->getInitializer()); // Enumerate the aliasees. for (llvm::Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end(); I != E; ++I) EnumerateValue(I->getAliasee()); // Enumerate the metadata type. // // TODO: Move this to ValueEnumerator::EnumerateOperandType() once bitcode // only encodes the metadata type when it's used as a value. EnumerateType(Type::getMetadataTy(M.getContext())); // Insert constants and metadata that are named at module level into the slot // pool so that the module symbol table can refer to them... EnumerateValueSymbolTable(M.getValueSymbolTable()); EnumerateNamedMetadata(M); SmallVector<std::pair<unsigned, MDNode *>, 8> MDs; // Enumerate types used by function bodies and argument lists. for (const Function &F : M) { for (const Argument &A : F.args()) EnumerateType(A.getType()); for (const BasicBlock &BB : F) for (const Instruction &I : BB) { for (const Use &Op : I.operands()) { auto *MD = dyn_cast<MetadataAsValue>(&Op); if (!MD) { EnumerateOperandType(Op); continue; } // Local metadata is enumerated during function-incorporation. if (isa<LocalAsMetadata>(MD->getMetadata())) continue; EnumerateMetadata(MD->getMetadata()); } EnumerateType(I.getType()); if (const CallInst *CI = dyn_cast<CallInst>(&I)) EnumerateAttributes(CI->getAttributes()); else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) EnumerateAttributes(II->getAttributes()); // Enumerate metadata attached with this instruction. MDs.clear(); I.getAllMetadataOtherThanDebugLoc(MDs); for (unsigned i = 0, e = MDs.size(); i != e; ++i) EnumerateMetadata(MDs[i].second); #if LLVM_VERSION >= 37 if (I.getDebugLoc()) { MDNode* Scope = I.getDebugLoc().getScope(); if (Scope) EnumerateMetadata(Scope); DILocation *IA = I.getDebugLoc().getInlinedAt(); if (IA) EnumerateMetadata(IA); } #else if (!I.getDebugLoc().isUnknown()) { MDNode *Scope, *IA; I.getDebugLoc().getScopeAndInlinedAt(Scope, IA, I.getContext()); if (Scope) EnumerateMetadata(Scope); if (IA) EnumerateMetadata(IA); } #endif } } // Optimize constant ordering. OptimizeConstants(FirstConstant, Values.size()); }