Exemple #1
0
/*
 * Instrument switch instructions to log the index of the taken branch.
 */
void PandaInstrumentVisitor::visitSwitchInst(SwitchInst &I){
    SExtInst *SEI;
    CallInst *CI;
    std::vector<Value*> argValues;
    Function *F = mod->getFunction("log_dynval");
    if (!F) {
        printf("Instrumentation function not found\n");
        assert(1==0);
    }
    if (I.getCondition()->getType() != wordType){
        SEI = static_cast<SExtInst*>(IRB.CreateSExt(I.getCondition(), wordType));
        argValues.push_back(ConstantInt::get(ptrType, (uintptr_t)dynval_buffer));
        argValues.push_back(ConstantInt::get(intType, SWITCHENTRY));
        argValues.push_back(ConstantInt::get(intType, SWITCH));
        argValues.push_back(static_cast<Value*>(SEI));
        CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
        CI->insertBefore(static_cast<Instruction*>(&I));
        SEI->insertBefore(static_cast<Instruction*>(CI));
    }
    else {
        argValues.push_back(ConstantInt::get(ptrType, (uintptr_t)dynval_buffer));
        argValues.push_back(ConstantInt::get(intType, SWITCHENTRY));
        argValues.push_back(ConstantInt::get(intType, SWITCH));
        argValues.push_back(static_cast<Value*>(I.getCondition()));
        CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
        CI->insertBefore(static_cast<Instruction*>(&I));
    }
}
Exemple #2
0
void replaceAllCallsWith(Value* OldFunc, Value* NewFunc) {
  
  for (Value::use_iterator I = OldFunc->use_begin(), E = OldFunc->use_end(); I != E; ++I) {

    if (CallInst* call = dyn_cast<CallInst>(*I)) {
    
      std::vector<Value*> args;
      for(int i=0; i<call->getNumArgOperands(); i++) {
        args.push_back(call->getArgOperand(i));
      }
      ArrayRef<Value*> Args(args);
  
      CallInst *newCall = CallInst::Create(NewFunc, Args);
      if (newCall->getType() != call->getType()) {
        if (call->use_begin() != call->use_end()) {
          errs() << "Cannot handle usage of non matching return types for " << *call->getType() << " and " << *newCall->getType() << "\n";
        }

        newCall->insertBefore(call);
        call->replaceAllUsesWith(newCall);
        call->eraseFromParent();
    
      } else {
        ReplaceInstWithInst(call, newCall);
      }
    } else {
      (*I)->print(errs()); errs() << "\n";
      exit(1);
    }
  }
}
Exemple #3
0
void PandaInstrumentVisitor::visitMemSetInst(MemSetInst &I){
    Function *F = mod->getFunction("log_dynval");
    if (!F) {
        printf("Instrumentation function not found\n");
        assert(1==0);
    }

    int bytes = 0;
    Value *length = I.getLength();
    if (ConstantInt* CI = dyn_cast<ConstantInt>(length)) {
        if (CI->getBitWidth() <= 64) {
            bytes = CI->getSExtValue();
        }
    }

    if (bytes > 100) {
        //This mostly happens in cpu state reset
        printf("Note: dyn log ignoring memset greater than 100 bytes\n");
        return;
    }

    PtrToIntInst *PTII;
    CallInst *CI;
    std::vector<Value*> argValues;
    PTII = static_cast<PtrToIntInst*>(IRB.CreatePtrToInt(
        I.getOperand(0), wordType));
    argValues.push_back(ConstantInt::get(ptrType,
        (uintptr_t)dynval_buffer));
    argValues.push_back(ConstantInt::get(intType, ADDRENTRY));
    argValues.push_back(ConstantInt::get(intType, STORE));
    argValues.push_back(static_cast<Value*>(PTII));
    CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
    CI->insertBefore(static_cast<Instruction*>(&I));
    PTII->insertBefore(static_cast<Instruction*>(CI));
}
void insert_function_limits(Function &F){
    
    //Functions to be inserted as pragmas
    FunctionType* funvoid = FunctionType::get(Type::getVoidTy( F.getParent()->getContext() ), false);
    
    InlineAsm* fun_begin;
    InlineAsm* fun_end;
    if (sizeof(void*)==sizeof(long long)){
        fun_begin = InlineAsm::get(funvoid, "callq\tpragma_function_begin", "", false);
        fun_end = InlineAsm::get(funvoid, "callq\tpragma_function_end", "", false);
    }
    else {
        fun_begin = InlineAsm::get(funvoid, "call\tpragma_function_begin", "", false);
        fun_end = InlineAsm::get(funvoid, "call\tpragma_function_end", "", false);
    }
    
    //In the beginning
    {
        BasicBlock& first = F.getEntryBlock();
        int preds = 0;
        for (pred_iterator pi = pred_begin(&first), pe = pred_end(&first); pi != pe; pi++){
            preds++;
        }
        if (preds > 0){
            report_fatal_error("Error: The first basic block has predecessor.\n");
            //TODO: insert a new basic block in the beginning
        }
        
        CallInst* before = CallInst::Create(fun_begin);
        before->setDoesNotThrow();
        before->insertBefore( first.getFirstNonPHI() );
    }
    
    //In the end
    for (Function::iterator bb = F.begin(), en = F.end(); bb != en; bb++){
        TerminatorInst* inst = bb->getTerminator();
        
        if ( isa<ReturnInst>(inst) ){
            CallInst* after = CallInst::Create(fun_end);
            after->setDoesNotThrow();
            //after->insertBefore( inst );
            after->insertBefore( bb->getFirstNonPHI() );
        }
    }
    
}
Exemple #5
0
void GEOSProfiler::instrumentBasicBlock(BasicBlock  &BB, Module &M, int ID) {
  IRBuilder<> Builder(BB.getContext());

  auto ConstantId = ConstantInt::get(Builder.getInt32Ty(), ID);
  CallInst *CountCall = Builder.CreateCall(
      M.getFunction("count"), ConstantId);

  CountCall->insertBefore(BB.getFirstNonPHI());
}
Exemple #6
0
/// CopyPrecedingStopPoint - If I is immediately preceded by a StopPoint,
/// make a copy of the stoppoint before InsertPos (presumably before copying
/// or moving I).
void llvm::CopyPrecedingStopPoint(Instruction *I, 
                                  BasicBlock::iterator InsertPos) {
  if (I != I->getParent()->begin()) {
    BasicBlock::iterator BBI = I;  --BBI;
    if (DbgStopPointInst *DSPI = dyn_cast<DbgStopPointInst>(BBI)) {
      CallInst *newDSPI = cast<CallInst>(DSPI->clone());
      newDSPI->insertBefore(InsertPos);
    }
  }
}
/**
 * Inserts new call instruction.
 * @param CalleeF function to be called
 * @param args arguments of the function to be called
 * @param rw_rule relevant rewrite rule
 * @param currentInstr current instruction
 * @param Iiterator pointer to instructions iterator
 */
void InsertCallInstruction(Function* CalleeF, vector<Value *> args,
                           RewriteRule rw_rule, Instruction *currentInstr,
                           inst_iterator *Iiterator) {
	// Create new call instruction
	CallInst *newInstr = CallInst::Create(CalleeF, args);

    // duplicate the metadata of the instruction for which we
    // instrument the code, some passes (e.g. inliner) can
    // break the code when there's an instruction without metadata
    // when all other instructions have metadata
    if (currentInstr->hasMetadata()) {
        CloneMetadata(currentInstr, newInstr);
    } else if (const DISubprogram *DS = currentInstr->getParent()->getParent()->getSubprogram()) {
        // no metadata? then it is going to be the instrumentation
        // of alloca or such at the beggining of function,
        // so just add debug loc of the beginning of the function
        newInstr->setDebugLoc(DebugLoc::get(DS->getLine(), 0, DS));
    }

	if(rw_rule.where == InstrumentPlacement::BEFORE) {
		// Insert before
		newInstr->insertBefore(currentInstr);
		logger.log_insertion("before", CalleeF, currentInstr);
	}
	else if(rw_rule.where == InstrumentPlacement::AFTER) {
		// Insert after
		newInstr->insertAfter(currentInstr);
		logger.log_insertion("after", CalleeF, currentInstr);
	}
	else if(rw_rule.where == InstrumentPlacement::REPLACE) {
		// TODO: Make the functions use the iterator instead of
		// the instruction then check this works
		// In the end we move the iterator to the newInst position
		// so we can safely remove the sequence of instructions being
		// replaced
		newInstr->insertAfter(currentInstr);
		inst_iterator helper(*Iiterator);
		*Iiterator = ++helper;
		EraseInstructions(currentInstr, rw_rule.foundInstrs.size());
		logger.log_insertion(rw_rule.foundInstrs, rw_rule.newInstr.instruction);
	}
}
/**
 * Inserts new call instruction for globals.
 * @param CalleeF function to be called
 * @param args arguments of the function to be called
 * @param currentInstr current instruction
 */
void InsertCallInstruction(Function* CalleeF, vector<Value *> args,
                           Instruction *currentInstr) {
	// Create new call instruction
	CallInst *newInstr = CallInst::Create(CalleeF, args);

    // duplicate the metadata of the instruction for which we
    // instrument the code, some passes (e.g. inliner) can
    // break the code when there's an instruction without metadata
    // when all other instructions have metadata
    if (currentInstr->hasMetadata()) {
        CloneMetadata(currentInstr, newInstr);
    } else if (const DISubprogram *DS = currentInstr->getParent()->getParent()->getSubprogram()) {
        // no metadata? then it is going to be the instrumentation
        // of alloca or such at the beggining of function,
        // so just add debug loc of the beginning of the function
        newInstr->setDebugLoc(DebugLoc::get(DS->getLine(), 0, DS));
    }

    // Insert before
    newInstr->insertBefore(currentInstr);
    logger.log_insertion("before", CalleeF, currentInstr);
}
Exemple #9
0
void FuncAddrTaken::addPatchAt(Module &M, FunctionType *FT,
                               Value *V, Instruction *MI,
                               std::map<BasicBlock*, std::set<std::string> >& UniqPatchAt) {
  if (isa<Function>(V) && cast<Function>(V)->hasName()) {
    StringRef fn = cast<Function>(V)->getName();
    if (fn.startswith("_GLOBAL__D_") || fn.startswith("_GLOBAL__E_"))
      return;
    std::string patchname = std::string("__patch_at") + fn.str();
    BasicBlock* BB = MI->getParent();
    if (UniqPatchAt.find(BB) == UniqPatchAt.end())
      UniqPatchAt[BB] = std::set<std::string>();
    if (UniqPatchAt[BB].find(patchname) != UniqPatchAt[BB].end())
      return;
    UniqPatchAt[BB].insert(patchname);
    IRBuilder<> Builder(M.getContext());
    Constant* PatchAtHere =
      M.getOrInsertFunction(
        std::string("__patch_at") + fn.str(), FT);
    CallInst *PatchAtCI =
      Builder.CreateCall(PatchAtHere);
    PatchAtCI->insertBefore(MI);
  }
}
Exemple #10
0
/// CreateGlobalPool - Create a global pool descriptor object, and insert a
/// poolinit for it into the global constructor.
GlobalVariable *
PoolAllocateSimple::CreateGlobalPool (unsigned RecSize,
                                      unsigned Align,
                                      Module& M) {
  //
  // See if the global pool has already been created.  If so, then just return
  // it.
  //
  if (GlobalVariable * GV = M.getNamedGlobal ("__poolalloc_GlobalPool")) {
    return GV;
  }

  //
  // Create the global pool descriptor.
  //
  GlobalVariable *GV =
    new GlobalVariable(M,
          getPoolType(&M.getContext()), false, GlobalValue::ExternalLinkage,
          ConstantAggregateZero::get(getPoolType(&M.getContext())),
		       "__poolalloc_GlobalPool"
        );

  //
  // Get the global pool constructor. Create and insert the poolinit call
  // inside it.
  //
  Function *InitFunc = createGlobalPoolCtor(M);
  Value *ElSize = ConstantInt::get(Int32Type, RecSize);
  Value *AlignV = ConstantInt::get(Int32Type, Align);
  Value *Opts[3] = { GV, ElSize, AlignV };

  CallInst *InitCall = CallInst::Create(PoolInit, Opts, "");
  InitCall->insertBefore(&InitFunc->getEntryBlock().front());

  return GV;
}
Exemple #11
0
/*
 * Instrument select instructions similar to how we instrument branches.
 */
void PandaInstrumentVisitor::visitSelectInst(SelectInst &I){
    BinaryOperator *BO;
    ZExtInst *ZEI;
    CallInst *CI;
    std::vector<Value*> argValues;
    Value *condition;
    Function *F = mod->getFunction("log_dynval");
    if (!F) {
        printf("Instrumentation function not found\n");
        assert(1==0);
    }
    condition = I.getCondition();
    BO = static_cast<BinaryOperator*>(IRB.CreateNot(condition));
    ZEI = static_cast<ZExtInst*>(IRB.CreateZExt(BO, wordType));
    argValues.push_back(ConstantInt::get(ptrType,
        (uintptr_t)dynval_buffer));
    argValues.push_back(ConstantInt::get(intType, SELECTENTRY));
    argValues.push_back(ConstantInt::get(intType, SELECT));
    argValues.push_back(static_cast<Value*>(ZEI));
    CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
    CI->insertBefore(static_cast<Instruction*>(&I));
    ZEI->insertBefore(static_cast<Instruction*>(CI));
    BO->insertBefore(static_cast<Instruction*>(ZEI));
}
Exemple #12
0
/*
 * Call the logging function, logging the address of the load.  If it's loading
 * the root of a global value (likely CPUState), then we can ignore it.
 */
void PandaInstrumentVisitor::visitLoadInst(LoadInst &I){
    Function *F = mod->getFunction("log_dynval");
    if (!F) {
        printf("Instrumentation function not found\n");
        assert(1==0);
    }
    // We used to ignore global values, but I think we will keep it now since
    // global QEMU values may be referenced in helper functions
    //if (!(isa<GlobalValue>(I.getPointerOperand()))){
        if (isa<GetElementPtrInst>(I.getPointerOperand())){
            // Result from a getelementptr instruction
            CallInst *CI;
            PtrToIntInst *PTII;
            std::vector<Value*> argValues;
            PTII = static_cast<PtrToIntInst*>(
                IRB.CreatePtrToInt(I.getPointerOperand(), ptrType));
            argValues.push_back(ConstantInt::get(ptrType,
                (uintptr_t)dynval_buffer));
            argValues.push_back(ConstantInt::get(intType, ADDRENTRY));
            argValues.push_back(ConstantInt::get(intType, LOAD));
            argValues.push_back(static_cast<Value*>(PTII));
            //argValues.push_back(static_cast<Value*>(I.getPointerOperand()));
            CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
            CI->insertBefore(static_cast<Instruction*>(&I));
            PTII->insertBefore(static_cast<Instruction*>(CI));
        }
        else if (
            // GetElementPtr ConstantExpr
            (isa<ConstantExpr>(I.getPointerOperand()) &&
                static_cast<ConstantExpr*>(I.getPointerOperand())->getOpcode()
                == Instruction::GetElementPtr)
            // IntToPtr ConstantExpr
            || (isa<ConstantExpr>(I.getPointerOperand()) &&
                static_cast<ConstantExpr*>(I.getPointerOperand())->getOpcode()
                == Instruction::IntToPtr)
            // env, or some other global variable
            || (isa<GlobalVariable>(I.getPointerOperand()))
            ){
            CallInst *CI;
            PtrToIntInst *PTII;
            std::vector<Value*> argValues;
            PTII = static_cast<PtrToIntInst*>(
                IRB.CreatePtrToInt(I.getPointerOperand(), ptrType));
            argValues.push_back(ConstantInt::get(ptrType,
                (uintptr_t)dynval_buffer));
            argValues.push_back(ConstantInt::get(intType, ADDRENTRY));
            argValues.push_back(ConstantInt::get(intType, LOAD));
            argValues.push_back(static_cast<Value*>(PTII));
            CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
            CI->insertBefore(static_cast<Instruction*>(&I));
        }
        else {
            PtrToIntInst *PTII;
            CallInst *CI;
            std::vector<Value*> argValues;
            PTII = static_cast<PtrToIntInst*>(IRB.CreatePtrToInt(
                I.getPointerOperand(), wordType));
            argValues.push_back(ConstantInt::get(ptrType,
                (uintptr_t)dynval_buffer));
            argValues.push_back(ConstantInt::get(intType, ADDRENTRY));
            argValues.push_back(ConstantInt::get(intType, LOAD));
            argValues.push_back(static_cast<Value*>(PTII));
            CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
            CI->insertBefore(static_cast<Instruction*>(&I));
            PTII->insertBefore(static_cast<Instruction*>(CI));
        }
    //}
}
Exemple #13
0
/*
 * Call the logging function, logging the branch target.  Target[0] is the true
 * branch, and target[1] is the false branch.  So when logging, we NOT the
 * condition to actually log the target taken.  We are also logging and
 * processing unconditional branches for the time being.
 */
void PandaInstrumentVisitor::visitBranchInst(BranchInst &I){
    BinaryOperator *BO;
    ZExtInst *ZEI;
    CallInst *CI;
    std::vector<Value*> argValues;
    Value *condition;
    Function *F = mod->getFunction("log_dynval");
    if (!F) {
        printf("Instrumentation function not found\n");
        assert(1==0);
    }
    if (I.isConditional()){
        condition = I.getCondition();
        if(isa<UndefValue>(condition)){
            BO = static_cast<BinaryOperator*>(IRB.CreateNot(condition));
            ZEI = static_cast<ZExtInst*>(IRB.CreateZExt(BO, wordType));
            argValues.push_back(ConstantInt::get(ptrType,
                (uintptr_t)dynval_buffer));
            argValues.push_back(ConstantInt::get(intType, BRANCHENTRY));
            argValues.push_back(ConstantInt::get(intType, BRANCHOP));
            argValues.push_back(static_cast<Value*>(ZEI));
            CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
            CI->insertBefore(static_cast<Instruction*>(&I));
        }
        else if (isa<Constant>(condition)){
            CallInst *CI;
            std::vector<Value*> argValues;
            uint64_t constcond = static_cast<ConstantInt*>(
                I.getCondition())->getZExtValue();
            argValues.push_back(ConstantInt::get(ptrType,
                (uintptr_t)dynval_buffer));
            argValues.push_back(ConstantInt::get(intType, BRANCHENTRY));
            argValues.push_back(ConstantInt::get(intType, BRANCHOP));
            argValues.push_back(ConstantInt::get(wordType, !constcond));
            CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
            CI->insertBefore(static_cast<Instruction*>(&I));
        }
        else {
            BO = static_cast<BinaryOperator*>(IRB.CreateNot(condition));
            ZEI = static_cast<ZExtInst*>(IRB.CreateZExt(BO, wordType));
            argValues.push_back(ConstantInt::get(ptrType,
                (uintptr_t)dynval_buffer));
            argValues.push_back(ConstantInt::get(intType, BRANCHENTRY));
            argValues.push_back(ConstantInt::get(intType, BRANCHOP));
            argValues.push_back(static_cast<Value*>(ZEI));
            CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
            CI->insertBefore(static_cast<Instruction*>(&I));
            ZEI->insertBefore(static_cast<Instruction*>(CI));
            BO->insertBefore(static_cast<Instruction*>(ZEI));
        }
    }
    else {
        argValues.push_back(ConstantInt::get(ptrType,
            (uintptr_t)dynval_buffer));
        argValues.push_back(ConstantInt::get(intType, BRANCHENTRY));
        argValues.push_back(ConstantInt::get(intType, BRANCHOP));
        argValues.push_back(ConstantInt::get(wordType, 0));
        CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
        CI->insertBefore(static_cast<Instruction*>(&I));
    }
}
Exemple #14
0
// Call the logging function, logging the address of the store
void PandaInstrumentVisitor::visitStoreInst(StoreInst &I){
    Function *F = mod->getFunction("log_dynval");
    if (!F) {
        printf("Instrumentation function not found\n");
        assert(1==0);
    }
    if (I.isVolatile()){
        // Stores to LLVM runtime that we don't care about
        return;
    }
    else if (isa<ConstantExpr>(I.getPointerOperand()) &&
                isa<Constant>(static_cast<Instruction*>(
                I.getPointerOperand())->getOperand(0))){
        /*
         * Storing to a constant looks something like this:
         * store i32 %29, i32* inttoptr (i64 135186980 to i32*),
         * sort of like an inttoptr instruction as an operand.  This is how we
         * deal with logging that weirdness.
         */
        CallInst *CI;
        std::vector<Value*> argValues;
        uint64_t constaddr = static_cast<ConstantInt*>(
            static_cast<Instruction*>(
                I.getPointerOperand())->getOperand(0))->getZExtValue();
        argValues.push_back(ConstantInt::get(ptrType,
            (uintptr_t)dynval_buffer));
        argValues.push_back(ConstantInt::get(intType, ADDRENTRY));
        argValues.push_back(ConstantInt::get(intType, STORE));
        argValues.push_back(ConstantInt::get(wordType, constaddr));
        CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
        CI->insertBefore(static_cast<Instruction*>(&I));
    }
    else if (isa<GlobalVariable>(I.getPointerOperand())){
    //else if (isa<GlobalValue>(I.getPointerOperand())){
        // env, or some other global variable
        CallInst *CI;
        PtrToIntInst *PTII;
        std::vector<Value*> argValues;
        PTII = static_cast<PtrToIntInst*>(
            IRB.CreatePtrToInt(I.getPointerOperand(), ptrType));
        argValues.push_back(ConstantInt::get(ptrType,
            (uintptr_t)dynval_buffer));
        argValues.push_back(ConstantInt::get(intType, ADDRENTRY));
        argValues.push_back(ConstantInt::get(intType, STORE));
        argValues.push_back(static_cast<Value*>(PTII));
        CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
        CI->insertBefore(static_cast<Instruction*>(&I));
    }
    else {
        PtrToIntInst *PTII;
        CallInst *CI;
        std::vector<Value*> argValues;
        PTII = static_cast<PtrToIntInst*>(IRB.CreatePtrToInt(
            I.getPointerOperand(), wordType));
        argValues.push_back(ConstantInt::get(ptrType,
            (uintptr_t)dynval_buffer));
        argValues.push_back(ConstantInt::get(intType, ADDRENTRY));
        argValues.push_back(ConstantInt::get(intType, STORE));
        argValues.push_back(static_cast<Value*>(PTII));
        CI = IRB.CreateCall(F, ArrayRef<Value*>(argValues));
        CI->insertBefore(static_cast<Instruction*>(&I));
        PTII->insertBefore(static_cast<Instruction*>(CI));
    }
}