/// Propagate dbg.value intrinsics through the newly inserted Phis. static void insertDebugValues(BasicBlock *OrigHeader, SmallVectorImpl<PHINode*> &InsertedPHIs) { ValueToValueMapTy DbgValueMap; // Map existing PHI nodes to their dbg.values. for (auto &I : *OrigHeader) { if (auto DbgII = dyn_cast<DbgInfoIntrinsic>(&I)) { if (auto *Loc = dyn_cast_or_null<PHINode>(DbgII->getVariableLocation())) DbgValueMap.insert({Loc, DbgII}); } } // Then iterate through the new PHIs and look to see if they use one of the // previously mapped PHIs. If so, insert a new dbg.value intrinsic that will // propagate the info through the new PHI. LLVMContext &C = OrigHeader->getContext(); for (auto PHI : InsertedPHIs) { for (auto VI : PHI->operand_values()) { auto V = DbgValueMap.find(VI); if (V != DbgValueMap.end()) { auto *DbgII = cast<DbgInfoIntrinsic>(V->second); Instruction *NewDbgII = DbgII->clone(); auto PhiMAV = MetadataAsValue::get(C, ValueAsMetadata::get(PHI)); NewDbgII->setOperand(0, PhiMAV); BasicBlock *Parent = PHI->getParent(); NewDbgII->insertBefore(Parent->getFirstNonPHIOrDbgOrLifetime()); } } } }
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); } }
void OMPGenerator::extractValuesFromStruct(SetVector<Value *> OldValues, Value *Struct, ValueToValueMapTy &Map) { for (unsigned i = 0; i < OldValues.size(); i++) { Value *Address = Builder.CreateStructGEP(Struct, i); Value *NewValue = Builder.CreateLoad(Address); Map.insert(std::make_pair(OldValues[i], NewValue)); } }
void DuettoNativeRewriter::rewriteConstructorImplementation(Module& M, Function& F) { //Copy the code in a function with the right signature Function* newFunc=getReturningConstructor(M, &F); if(!newFunc->empty()) return; //Visit each instruction and take note of the ones that needs to be replaced Function::const_iterator B=F.begin(); Function::const_iterator BE=F.end(); ValueToValueMapTy valueMap; CallInst* lowerConstructor = NULL; const CallInst* oldLowerConstructor = NULL; for(;B!=BE;++B) { BasicBlock::const_iterator I=B->begin(); BasicBlock::const_iterator IE=B->end(); for(;I!=IE;++I) { if(I->getOpcode()!=Instruction::Call) continue; const CallInst* callInst=cast<CallInst>(&(*I)); Function* f=callInst->getCalledFunction(); if(!f) continue; const char* startOfType; const char* endOfType; if(!DuettoNativeRewriter::isBuiltinConstructor(f->getName().data(), startOfType, endOfType)) continue; //Check that the constructor is for 'this' if(callInst->getOperand(0)!=F.arg_begin()) continue; //If this is another constructor for the same type, change it to a //returning constructor and use it as the 'this' argument Function* newFunc = getReturningConstructor(M, f); llvm::SmallVector<Value*, 4> newArgs; for(unsigned i=1;i<callInst->getNumArgOperands();i++) newArgs.push_back(callInst->getArgOperand(i)); lowerConstructor = CallInst::Create(newFunc, newArgs); oldLowerConstructor = callInst; break; } if(lowerConstructor) break; } //Clone the linkage first newFunc->setLinkage(F.getLinkage()); Function::arg_iterator origArg=++F.arg_begin(); Function::arg_iterator newArg=newFunc->arg_begin(); valueMap.insert(make_pair(F.arg_begin(), lowerConstructor)); for(unsigned i=1;i<F.arg_size();i++) { valueMap.insert(make_pair(&(*origArg), &(*newArg))); ++origArg; ++newArg; } SmallVector<ReturnInst*, 4> returns; CloneFunctionInto(newFunc, &F, valueMap, false, returns); //Find the right place to add the base construtor call assert(lowerConstructor->getNumArgOperands()<=1 && "Native constructors with multiple args are not supported"); Instruction* callPred = NULL; if (lowerConstructor->getNumArgOperands()==1 && Instruction::classof(lowerConstructor->getArgOperand(0))) { //Switch the argument to the one in the new func lowerConstructor->setArgOperand(0, valueMap[lowerConstructor->getArgOperand(0)]); callPred = cast<Instruction>(lowerConstructor->getArgOperand(0)); } else callPred = &newFunc->getEntryBlock().front(); //Add add it lowerConstructor->insertAfter(callPred); //Override the returs values for(unsigned i=0;i<returns.size();i++) { Instruction* newInst = ReturnInst::Create(M.getContext(),lowerConstructor); newInst->insertBefore(returns[i]); returns[i]->removeFromParent(); } //Recursively move all the users of the lower constructor after the call itself Instruction* insertPoint = lowerConstructor->getNextNode(); SmallVector<Value*, 4> usersQueue(lowerConstructor->getNumUses()); unsigned int i; Value::use_iterator it; for(i=usersQueue.size()-1,it=lowerConstructor->use_begin();it!=lowerConstructor->use_end();++it,i--) usersQueue[i]=it->getUser(); SmallSet<Instruction*, 4> movedInstructions; while(!usersQueue.empty()) { Instruction* cur=dyn_cast<Instruction>(usersQueue.pop_back_val()); if(!cur) continue; if(movedInstructions.count(cur)) continue; movedInstructions.insert(cur); cur->moveBefore(insertPoint); //Add users of this instrucution as well usersQueue.resize(usersQueue.size()+cur->getNumUses()); for(i=usersQueue.size()-1,it=cur->use_begin();it!=cur->use_end();++it,i--) usersQueue[i]=it->getUser(); } cast<Instruction>(valueMap[oldLowerConstructor])->eraseFromParent(); }
Function* specializeFunction(Function *f, Value*const* args) // make a copy of f // specialize on the arguments, a null means that that argument isn't known { assert(!f->isDeclaration()); ValueToValueMapTy vmap; unsigned int i = 0; unsigned int j = 0; std::vector<std::string> argNames; std::string baseName = specializeName(f, argNames); for (Function::arg_iterator itr = f->arg_begin(); itr != f->arg_end(); itr++, i++) { while (argNames[j] != "?") j++; if (args[i] != NULL) { Value* arg = (Value*) &(*itr); assert(arg->getType() == args[i]->getType() && "Specializing argument with concrete value of wrong type!"); vmap.insert(std::pair<Value*, WeakVH>(arg, args[i])); PrevirtType pt = PrevirtType::abstract(args[i]); argNames[j] = pt.to_string(); /* if (const ConstantInt* ci = dyn_cast<const ConstantInt> (args[i])) { argNames[j] = ci->getValue().toString(10, true); } else if (const Constant* c = dyn_cast<const Constant>(args[i])) { if (c->isNullValue()) { argNames[j] = "null"; } else { assert(false); } } else if (const ) } else { assert(false); } */ } j++; } assert (i == f->getArgumentList().size()); baseName += "("; for (std::vector<std::string>::const_iterator it = argNames.begin(), be = argNames.begin(), en = argNames.end(); it != en; ++it) { if (it != be) baseName += ","; baseName += *it; } baseName += ")"; Function *result = f->getParent()->getFunction(baseName); // If specialized function already exists, no reason // to create another one. In fact, can cause the process // to diverge. XXX This needs to be a more sophisticated // check if (!result) { ClonedCodeInfo info; result = llvm::CloneFunction(f, vmap, true, &info); result->setName(baseName); } return result; }