예제 #1
0
파일: Local.cpp 프로젝트: brills/pfpa
void GraphBuilder::visitPtrToIntInst(PtrToIntInst& I) {
  DSNode* N = getValueDest(I.getOperand(0)).getNode();
  if(I.hasOneUse()) {
    if(isa<ICmpInst>(*(I.use_begin()))) {
      NumBoringIntToPtr++;
      return;
    }
  }
  if(I.hasOneUse()) {
    Value *V = dyn_cast<Value>(*(I.use_begin()));
    DenseSet<Value *> Seen;
    while(V && V->hasOneUse() &&
          Seen.insert(V).second) {
      if(isa<LoadInst>(V))
        break;
      if(isa<StoreInst>(V))
        break;
      if(isa<CallInst>(V))
        break;
      V = dyn_cast<Value>(*(V->use_begin()));
    }
    if(isa<BranchInst>(V)){
      NumBoringIntToPtr++;
      return;
    }
  }
  if(N)
    N->setPtrToIntMarker();
}
예제 #2
0
bool CallAnalyzer::visitPtrToInt(PtrToIntInst &I) {
  // Propagate constants through ptrtoint.
  if (Constant *COp = dyn_cast<Constant>(I.getOperand(0)))
    if (Constant *C = ConstantExpr::getPtrToInt(COp, I.getType())) {
      SimplifiedValues[&I] = C;
      return true;
    }

  // Track base/offset pairs when converted to a plain integer provided the
  // integer is large enough to represent the pointer.
  unsigned IntegerSize = I.getType()->getScalarSizeInBits();
  if (TD && IntegerSize >= TD->getPointerSizeInBits()) {
    std::pair<Value *, APInt> BaseAndOffset
      = ConstantOffsetPtrs.lookup(I.getOperand(0));
    if (BaseAndOffset.first)
      ConstantOffsetPtrs[&I] = BaseAndOffset;
  }

  // This is really weird. Technically, ptrtoint will disable SROA. However,
  // unless that ptrtoint is *used* somewhere in the live basic blocks after
  // inlining, it will be nuked, and SROA should proceed. All of the uses which
  // would block SROA would also block SROA if applied directly to a pointer,
  // and so we can just add the integer in here. The only places where SROA is
  // preserved either cannot fire on an integer, or won't in-and-of themselves
  // disable SROA (ext) w/o some later use that we would see and disable.
  Value *SROAArg;
  DenseMap<Value *, int>::iterator CostIt;
  if (lookupSROAArgAndCost(I.getOperand(0), SROAArg, CostIt))
    SROAArgValues[&I] = SROAArg;

  return isInstructionFree(&I, TD);
}
예제 #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 GCInvariantVerifier::visitPtrToIntInst(PtrToIntInst &PII) {
    Check(!isSpecialAS(PII.getPointerAddressSpace()),
          "Illegal inttoptr", &PII);
}
예제 #5
0
파일: Iago.cpp 프로젝트: EspressoZhao/SVA
//
// Method: addBitMasking()
//
// Description:
//  Add code before the specified instruction to perform the appropriate
//  bit-masking of the specified pointer.
//
Value *
Iago::addBitMasking (Value * Pointer, Instruction & I) {
  //
  // Create the integer values used for bit-masking.
  //
  TargetData & TD = getAnalysis<TargetData>();
  Type * IntPtrTy = TD.getIntPtrType(I.getContext());
  Value * CheckMask = ConstantInt::get (IntPtrTy, checkMask);
  Value * SetMask   = ConstantInt::get (IntPtrTy, setMask);
  Value * Zero      = ConstantInt::get (IntPtrTy, 0u);
  Value * ThirtyTwo = ConstantInt::get (IntPtrTy, 32u);

  //
  // Convert the pointer into an integer and then shift the higher order bits
  // into the lower-half of the integer.  Bit-masking operations can use
  // constant operands, reducing register pressure, if the operands are 32-bits
  // or smaller.
  //
  PtrToIntInst * CastedPointer = new PtrToIntInst(Pointer, IntPtrTy, "ptr", &I);
  Value * PtrHighBits = BinaryOperator::Create (Instruction::LShr,
                                                CastedPointer,
                                                ThirtyTwo,
                                                "highbits",
                                                &I);
                                                    
#if 1
#if 1
  //
  // Create an instruction to mask off the proper bits to see if the pointer
  // is within the secure memory range.
  //
  Value * CheckMasked = BinaryOperator::Create (Instruction::And,
                                                PtrHighBits,
                                                CheckMask,
                                                "checkMask",
                                                &I);
#endif

  //
  // Compare the masked pointer to the mask.  If they're the same, we need to
  // set that bit.
  //
#if 1
  Value * Cmp = new ICmpInst (&I,
                              CmpInst::ICMP_EQ,
                              CheckMasked,
                              CheckMask,
                              "cmp");
#else
  Value * Cmp = new ICmpInst (&I,
                              CmpInst::ICMP_ULE,
                              CheckMask,
                              CastedPointer,
                              "cmp");
#endif

  //
  // Create the select instruction that, at run-time, will determine if we use
  // the bit-masked pointer or the original pointer value.
  //
  Value * MaskValue = SelectInst::Create (Cmp, SetMask, Zero, "ptr", &I);

  //
  // Create instructions that create a version of the pointer with the proper
  // bit set.
  //
  Value * Masked = BinaryOperator::Create (Instruction::Or,
                                           CastedPointer,
                                           MaskValue,
                                           "setMask",
                                           &I);

  //
  // Now replace all uses of the original instruction with this one.  Be sure
  // to fixup instructions we created that need to use the old value.
  //
  Masked = new IntToPtrInst (Masked, Pointer->getType(), "masked", &I);
  Pointer->replaceAllUsesWith (Masked);
  CastedPointer->replaceUsesOfWith (Masked, Pointer);

  return (Masked);
#else
  Module * M = I.getParent()->getParent()->getParent();
  Function * CheckFunction = cast<Function>(M->getFunction ("sva_checkptr"));
  assert (CheckFunction && "CheckFunction not found!\n");
  CallInst::Create (CheckFunction, CastedPointer, "", &I);
  return Pointer;
#endif
}
예제 #6
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));
        }
    //}
}
예제 #7
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));
    }
}