예제 #1
0
파일: ReachingDefs.cpp 프로젝트: Justme0/dg
bool LLVMReachingDefsAnalysis::handleStoreInst(LLVMNode *storeNode, DefMap *df,
                                               PointsToSetT *&strong_update)
{
    bool changed = false;
    llvm::StoreInst *SI = cast<StoreInst>(storeNode->getValue());
    LLVMNode *ptrNode = getOperand(storeNode, SI->getPointerOperand(), 0);
    assert(ptrNode && "No pointer operand");

    // update definitions
    PointsToSetT& S = ptrNode->getPointsTo();
    // if we have only one concrete pointer (known pointer
    // with known offset), it is safe to do strong update
    if (S.size() == 1) {
        const Pointer& ptr = *S.begin();
        // NOTE: we don't have good mechanism to diferentiate
        // heap-allocated objects yet, so if the pointer points to heap,
        // we must do weak update
        if (ptr.isKnown() && !ptr.offset.isUnknown() && !ptr.pointsToHeap()) {
            changed |= df->update(ptr, storeNode);
            strong_update = &S;
            return changed;
        }

        // else fall-through to weak update
    }

    // weak update
    for (const Pointer& ptr : ptrNode->getPointsTo())
        changed |= df->add(ptr, storeNode);

    return changed;
}
예제 #2
0
파일: ReachingDefs.cpp 프로젝트: Justme0/dg
bool LLVMReachingDefsAnalysis::handleIntrinsicCall(LLVMNode *callNode,
                                                   CallInst *CI,
                                                   DefMap *df)
{
    bool changed = false;
    IntrinsicInst *I = cast<IntrinsicInst>(CI);
    Value *dest;

    switch (I->getIntrinsicID())
    {
        case Intrinsic::memmove:
        case Intrinsic::memcpy:
        case Intrinsic::memset:
            dest = I->getOperand(0);
            break;
        default:
            return handleUndefinedCall(callNode, CI, df);
    }

    LLVMNode *destNode = getOperand(callNode, dest, 1);
    assert(destNode && "No operand for intrinsic call");

    for (const Pointer& ptr : destNode->getPointsTo()) {
        // we could compute all the concrete offsets, but
        // these functions usually set the whole memory,
        // so if we use UNKNOWN_OFFSET, the effect is the same
        changed |= df->add(Pointer(ptr.obj, UNKNOWN_OFFSET), callNode);
    }

    return changed;
}
예제 #3
0
파일: ReachingDefs.cpp 프로젝트: Justme0/dg
bool LLVMReachingDefsAnalysis::handleUndefinedCall(LLVMNode *callNode,
                                                   CallInst *CI,
                                                   DefMap *df)
{
    bool changed = false;
    for (unsigned n = 1, e = callNode->getOperandsNum(); n < e; ++n) {
        Value *llvmOp = CI->getOperand(n - 1);
        if (!llvmOp->getType()->isPointerTy())
            continue;

        if (isa<Constant>(llvmOp->stripInBoundsOffsets()))
            continue;

        LLVMNode *op = getOperand(callNode, llvmOp, n);
        assert(op && "unhandled pointer operand in undef call");

        // with undefined call we must assume that any
        // memory that was passed via pointer was modified
        // and on unknown offset
        // XXX we should handle external globals too
        for (const Pointer& ptr : op->getPointsTo())
            changed |= df->add(Pointer(ptr.obj, UNKNOWN_OFFSET), callNode);
    }

    return changed;
}