コード例 #1
0
ファイル: Calls.cpp プロジェクト: tomsik68/dg
PSNodesSeq
LLVMPointerSubgraphBuilder::createVarArg(const llvm::IntrinsicInst *Inst)
{
    // just store all the pointers from vararg argument
    // to the memory given in vastart() on Offset::UNKNOWN.
    // It is the easiest thing we can do without any further
    // analysis

    // first we need to get the vararg argument phi
    const llvm::Function *F = Inst->getParent()->getParent();
    Subgraph& subg = subgraphs_map[F];
    PSNode *arg = subg.vararg;
    assert(F->isVarArg() && "vastart in a non-variadic function");
    assert(arg && "Don't have variadic argument in a variadic function");

    // vastart will be node that will keep the memory
    // with pointers, its argument is the alloca, that
    // alloca will keep pointer to vastart
    PSNode *vastart = PS.create(PSNodeType::ALLOC);

    // vastart has only one operand which is the struct
    // it uses for storing the va arguments. Strip it so that we'll
    // get the underlying alloca inst
    PSNode *op = getOperand(Inst->getOperand(0)->stripInBoundsOffsets());
    // the argument is usually an alloca, but it may be a load
    // in the case the code was transformed by -reg2mem
    assert((op->getType() == PSNodeType::ALLOC || op->getType() == PSNodeType::LOAD)
           && "Argument of vastart is invalid");
    // get node with the same pointer, but with Offset::UNKNOWN
    // FIXME: we're leaking it
    // make the memory in alloca point to our memory in vastart
    PSNode *ptr = PS.create(PSNodeType::GEP, op, Offset::UNKNOWN);
    PSNode *S1 = PS.create(PSNodeType::STORE, vastart, ptr);
    // and also make vastart point to the vararg args
    PSNode *S2 = PS.create(PSNodeType::STORE, arg, vastart);

    vastart->addSuccessor(ptr);
    ptr->addSuccessor(S1);
    S1->addSuccessor(S2);

    // set paired node to S2 for vararg, so that when adding structure,
    // we add the whole sequence (it adds from call-node to pair-node,
    // because of the old system where we did not store all sequences)
    // FIXME: fix this
    vastart->setPairedNode(S2);

    // FIXME: we're assuming that in a sequence in the nodes_map
    // is always the last node the 'real' node. In this case it is not true,
    // so add only the 'vastart', so that we have the mapping in nodes_map
    addNode(Inst, vastart);

    return PSNodesSeq(vastart, S2);
}
コード例 #2
0
ファイル: Calls.cpp プロジェクト: tomsik68/dg
PSNodesSeq
LLVMPointerSubgraphBuilder::createUnknownCall(const llvm::CallInst *CInst)
{
    // This assertion must not hold if the call is wrapped
    // inside bitcast - it defaults to int, but is bitcased
    // to pointer
    //assert(CInst->getType()->isPointerTy());
    PSNode *call = PS.create(PSNodeType::CALL, nullptr);

    call->setPairedNode(call);

    // the only thing that the node will point at
    call->addPointsTo(PointerUnknown);

    addNode(CInst, call);

    return std::make_pair(call, call);
}
コード例 #3
0
ファイル: Calls.cpp プロジェクト: tomsik68/dg
PSNode *
LLVMPointerSubgraphBuilder::createAsm(const llvm::Instruction *Inst)
{
    // we filter irrelevant calls in isRelevantCall()
    // and we don't have assembler there at all. If
    // we are here, then we got here because this
    // is undefined call that returns pointer.
    // In this case return an unknown pointer
    static bool warned = false;
    if (!warned) {
        llvm::errs() << "PTA: Inline assembly found, analysis  may be unsound\n";
        warned = true;
    }

    PSNode *n = PS.create(PSNodeType::CONSTANT, UNKNOWN_MEMORY, Offset::UNKNOWN);
    // it is call that returns pointer, so we'd like to have
    // a 'return' node that contains that pointer
    n->setPairedNode(n);
    addNode(Inst, n);

    return n;
}