예제 #1
0
/// 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());
      }
    }
  }
}
예제 #2
0
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);
	}
}
예제 #3
0
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));
  }
}
예제 #4
0
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();
}
예제 #5
0
  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;
  }