Пример #1
0
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
PSNodesSeq
LLVMPointerSubgraphBuilder::createRealloc(const llvm::CallInst *CInst)
{
    using namespace llvm;

    // we create new allocation node and memcpy old pointers there
    PSNode *orig_mem = getOperand(CInst->getOperand(0));
    PSNodeAlloc *reall = PSNodeAlloc::get(PS.create(PSNodeType::DYN_ALLOC));
    // copy everything that is in orig_mem to reall
    PSNode *mcp = PS.create(PSNodeType::MEMCPY, orig_mem, reall, Offset::UNKNOWN);
    // we need the pointer in the last node that we return
    PSNode *ptr = PS.create(PSNodeType::CONSTANT, reall, 0);

    reall->setIsHeap();
    reall->setSize(getConstantSizeValue(CInst->getOperand(1)));

    reall->addSuccessor(mcp);
    mcp->addSuccessor(ptr);

    reall->setUserData(const_cast<llvm::CallInst *>(CInst));

    PSNodesSeq ret = PSNodesSeq(reall, ptr);
    addNode(CInst, ret);

    return ret;
}
Пример #3
0
PSNodesSeq
LLVMPointerSubgraphBuilder::createMemSet(const llvm::Instruction *Inst)
{
    PSNode *val;
    if (memsetIsZeroInitialization(llvm::cast<llvm::IntrinsicInst>(Inst)))
        val = NULLPTR;
    else
        // if the memset is not 0-initialized, it does some
        // garbage into the pointer
        val = UNKNOWN_MEMORY;

    PSNode *op = getOperand(Inst->getOperand(0)->stripInBoundsOffsets());
    // we need to make unknown offsets
    PSNode *G = PS.create(PSNodeType::GEP, op, Offset::UNKNOWN);
    PSNode *S = PS.create(PSNodeType::STORE, val, G);
    G->addSuccessor(S);

    PSNodesSeq ret = PSNodesSeq(G, S);
    addNode(Inst, ret);

    return ret;
}