Skip to content

Commit

Permalink
Merge branch 'SVF-tools:master' into cmake_modernisation
Browse files Browse the repository at this point in the history
  • Loading branch information
Johanmyst authored Jan 4, 2024
2 parents f39e656 + 3e91368 commit 9de179f
Show file tree
Hide file tree
Showing 28 changed files with 387 additions and 296 deletions.
4 changes: 0 additions & 4 deletions svf-llvm/include/SVF-LLVM/LLVMUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,6 @@ static inline Type* getPtrElementType(const PointerType* pty)
#endif
}

/// Infer type based on llvm value, this is for the migration to opaque pointer
/// please refer to: https://llvm.org/docs/OpaquePointers.html#migration-instructions
Type *getPointeeType(const Value *value);

/// Get the reference type of heap/static object from an allocation site.
//@{
const Type *inferTypeOfHeapObjOrStaticObj(const Instruction* inst);
Expand Down
65 changes: 0 additions & 65 deletions svf-llvm/lib/LLVMUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,71 +241,6 @@ const Value* LLVMUtil::stripConstantCasts(const Value* val)
return val;
}

/// Infer type based on llvm value, this is for the migration to opaque pointer
/// please refer to: https://llvm.org/docs/OpaquePointers.html#migration-instructions
Type *LLVMUtil::getPointeeType(const Value *value)
{
assert(value && "value cannot be nullptr!");
if (const LoadInst *loadInst = SVFUtil::dyn_cast<LoadInst>(value))
{
// get the pointee type of rhs based on lhs
// e.g., for `%lhs = load i64, ptr %rhs`, we return i64
return loadInst->getType();
}
else if (const StoreInst *storeInst = SVFUtil::dyn_cast<StoreInst>(value))
{
// get the pointee type of op1 based on op0
// e.g., for `store i64 %op0, ptr %op1`, we return i64
return storeInst->getValueOperand()->getType();
}
else if (const GetElementPtrInst *gepInst = SVFUtil::dyn_cast<GetElementPtrInst>(value))
{
// get the source element type of a gep instruction
// e.g., for `gep %struct.foo, ptr %base, i64 0`, we return struct.foo
return gepInst->getSourceElementType();
}
else if (const GEPOperator* gepOperator = SVFUtil::dyn_cast<GEPOperator>(value))
{
// get the source element type of a gep instruction
// e.g., for `gep %struct.foo, ptr %base, i64 0`, we return struct.foo
return gepOperator->getSourceElementType();
}
else if (const CallInst *callInst = SVFUtil::dyn_cast<CallInst>(value))
{
// get the pointee type of return value
// e.g., for `%call = call ptr @_Znwm(i64 noundef 8)`, we return i64
return callInst->getFunctionType();
}
else if (const CallBase *callBase = SVFUtil::dyn_cast<CallBase>(value))
{
// get the pointee type of return value
// e.g., for `%call = call ptr @_Znwm(i64 noundef 8)`, we return i64
return callBase->getFunctionType();
}
else if (const AllocaInst *allocaInst = SVFUtil::dyn_cast<AllocaInst>(value))
{
// get the type of the allocated memory
// e.g., for `%retval = alloca i64, align 4`, we return i64
return allocaInst->getAllocatedType();
}
else if (const GlobalVariable *globalVar = SVFUtil::dyn_cast<GlobalVariable>(value))
{
// get the pointee type of the global pointer
return globalVar->getValueType();
}
else if (const Function* func = SVFUtil::dyn_cast<Function>(value))
{
// get the pointee type of return value
// e.g., for `%call = call ptr @_Znwm(i64 noundef 8)`, we return i64
return func->getFunctionType();
}
else
{
assert(false && (LLVMUtil::dumpValue(value) + "Unknown llvm Type, cannot get Ptr Element Type").c_str());
abort();
}
}

void LLVMUtil::viewCFG(const Function* fun)
{
if (fun != nullptr)
Expand Down
7 changes: 6 additions & 1 deletion svf-llvm/lib/SVFIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -282,11 +282,16 @@ bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ap)

bool isConst = true;

bool prevPtrOperand = false;
for (bridge_gep_iterator gi = bridge_gep_begin(*V), ge = bridge_gep_end(*V);
gi != ge; ++gi)
{
const Type* gepTy = *gi;
const SVFType* svfGepTy = LLVMModuleSet::getLLVMModuleSet()->getSVFType(gepTy);

assert((prevPtrOperand && svfGepTy->isPointerTy()) == false &&
"Expect no more than one gep operand to be of a pointer type");
if(svfGepTy->isPointerTy()) prevPtrOperand = true;
const Value* offsetVal = gi.getOperand();
const SVFValue* offsetSvfVal = LLVMModuleSet::getLLVMModuleSet()->getSVFValue(offsetVal);
assert(gepTy != offsetVal->getType() && "iteration and operand have the same type?");
Expand Down Expand Up @@ -318,7 +323,7 @@ bool SVFIRBuilder::computeGepOffset(const User *V, AccessPath& ap)
// If it's a non-constant offset access
// If its point-to target is struct or array, it's likely an array accessing (%result = gep %struct.A* %a, i32 %non-const-index)
// If its point-to target is single value (pointer arithmetic), then it's a variant gep (%result = gep i8* %p, i32 %non-const-index)
if(!op && gepTy->isPointerTy() && LLVMUtil::getPointeeType(V)->isSingleValueType())
if(!op && gepTy->isPointerTy() && gepOp->getSourceElementType()->isSingleValueType())
{
isConst = false;
}
Expand Down
31 changes: 22 additions & 9 deletions svf-llvm/lib/SymbolTableBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -234,13 +234,8 @@ void SymbolTableBuilder::buildMemModel(SVFModule* svfModule)

void SymbolTableBuilder::collectSVFTypeInfo(const Value* val)
{
(void)getOrAddSVFTypeInfo(val->getType());
if (const PointerType * ptrType = SVFUtil::dyn_cast<PointerType>(val->getType()))
{
// TODO: getPtrElementType to be removed
const Type* objtype = LLVMUtil::getPtrElementType(ptrType);
(void)getOrAddSVFTypeInfo(objtype);
}
Type *valType = val->getType();
(void)getOrAddSVFTypeInfo(valType);
if(isGepConstantExpr(val) || SVFUtil::isa<GetElementPtrInst>(val))
{
for (bridge_gep_iterator
Expand Down Expand Up @@ -590,12 +585,30 @@ ObjTypeInfo* SymbolTableBuilder::createObjTypeInfo(const Value* val)
// (2) Other objects (e.g., alloca, global, etc.)
else
{
if(const PointerType* refTy = SVFUtil::dyn_cast<PointerType>(val->getType()))
objTy = getPtrElementType(refTy);
if (SVFUtil::isa<PointerType>(val->getType()))
{
if (const AllocaInst *allocaInst = SVFUtil::dyn_cast<AllocaInst>(val))
{
// get the type of the allocated memory
// e.g., for `%retval = alloca i64, align 4`, we return i64
objTy = allocaInst->getAllocatedType();
}
else if (const GlobalValue *global = SVFUtil::dyn_cast<GlobalValue>(val))
{
// get the pointee type of the global pointer (begins with @ symbol in llvm)
objTy = global->getValueType();
}
else
{
SVFUtil::errs() << dumpValue(val) << "\n";
assert(false && "not an allocation or global?");
}
}
}

if (objTy)
{
(void) getOrAddSVFTypeInfo(objTy);
ObjTypeInfo* typeInfo = new ObjTypeInfo(
LLVMModuleSet::getLLVMModuleSet()->getSVFType(objTy),
Options::MaxFieldLimit());
Expand Down
58 changes: 58 additions & 0 deletions svf/include/CFL/CFLSVFGBuilder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//===- CFLSVFGBuilder.h -- Building SVFG for CFL--------------------------//
//
// SVF: Static Value-Flow Analysis
//
// Copyright (C) <2013-> <Yulei Sui>
//

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.

// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//
//===----------------------------------------------------------------------===//

//
// Created by Xiao on 30/12/23.
//

#ifndef SVF_CFLSVFGBUILDER_H
#define SVF_CFLSVFGBUILDER_H

#include "SABER/SaberSVFGBuilder.h"

namespace SVF
{

class CFLSVFGBuilder: public SaberSVFGBuilder
{
public:
typedef Set<const SVFGNode*> SVFGNodeSet;
typedef Map<NodeID, PointsTo> NodeToPTSSMap;
typedef FIFOWorkList<NodeID> WorkList;

/// Constructor
CFLSVFGBuilder() = default;

/// Destructor
virtual ~CFLSVFGBuilder() = default;

protected:
/// Re-write create SVFG method
virtual void buildSVFG();

/// Remove Incoming Edge for strong-update (SU) store instruction
/// Because the SU node does not receive indirect value
virtual void rmIncomingEdgeForSUStore(BVDataPTAImpl* pta);
};

}
#endif //SVF_CFLSVFGBUILDER_H
4 changes: 2 additions & 2 deletions svf/include/CFL/CFLVF.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

#include "CFL/CFLBase.h"
#include "CFL/CFLStat.h"
#include "SABER/SaberSVFGBuilder.h"
#include "CFL/CFLSVFGBuilder.h"
#include "WPA/Andersen.h"

namespace SVF
Expand All @@ -59,7 +59,7 @@ class CFLVF : public CFLBase
void buildCFLGraph();

private:
SaberSVFGBuilder memSSA;
CFLSVFGBuilder memSSA;
SVFG* svfg;
};

Expand Down
24 changes: 15 additions & 9 deletions svf/include/DDA/DDAVFSolver.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,17 +189,23 @@ class DDAVFSolver
backtraceAlongDirectVF(gepPts,dpm);
unionDDAPts(pts, processGepPts(SVFUtil::cast<GepSVFGNode>(node),gepPts));
}
else if(SVFUtil::isa<LoadSVFGNode>(node))
else if(const LoadSVFGNode* load = SVFUtil::dyn_cast<LoadSVFGNode>(node))
{
if(load->getPAGDstNode()->isPointer() == false)
return;

CPtSet loadpts;
startNewPTCompFromLoadSrc(loadpts,dpm);
for(typename CPtSet::iterator it = loadpts.begin(), eit = loadpts.end(); it!=eit; ++it)
{
backtraceAlongIndirectVF(pts,getDPImWithOldCond(dpm,*it,node));
backtraceAlongIndirectVF(pts,getDPImWithOldCond(dpm,*it,load));
}
}
else if(SVFUtil::isa<StoreSVFGNode>(node))
else if(const StoreSVFGNode* store = SVFUtil::dyn_cast<StoreSVFGNode>(node))
{
if(store->getPAGSrcNode()->isPointer() == false)
return;

if(isMustAlias(getLoadDpm(dpm),dpm))
{
DBOUT(DDDA, SVFUtil::outs() << "+++must alias for load and store:");
Expand All @@ -217,17 +223,17 @@ class DDAVFSolver
{
if(propagateViaObj(*it,getLoadCVar(dpm)))
{
backtraceToStoreSrc(pts,getDPImWithOldCond(dpm,*it,node));
backtraceToStoreSrc(pts,getDPImWithOldCond(dpm,*it,store));

if(isStrongUpdate(storepts,SVFUtil::cast<StoreSVFGNode>(node)))
if(isStrongUpdate(storepts,store))
{
DBOUT(DDDA, SVFUtil::outs() << "backward strong update for obj " << dpm.getCurNodeID() << "\n");
DOSTAT(addSUStat(dpm,node);)
DOSTAT(addSUStat(dpm,store);)
}
else
{
DOSTAT(rmSUStat(dpm,node);)
backtraceAlongIndirectVF(pts,getDPImWithOldCond(dpm,*it,node));
DOSTAT(rmSUStat(dpm,store);)
backtraceAlongIndirectVF(pts,getDPImWithOldCond(dpm,*it,store));
}
}
else
Expand Down Expand Up @@ -347,7 +353,7 @@ class DDAVFSolver
{
const SVFGNode* node = oldDpm.getLoc();
NodeID obj = oldDpm.getCurNodeID();
if (_pag->isConstantObj(obj) || _pag->isNonPointerObj(obj))
if (_pag->isConstantObj(obj))
return;
const SVFGEdgeSet edgeSet(node->getInEdges());
for (SVFGNode::const_iterator it = edgeSet.begin(), eit = edgeSet.end(); it != eit; ++it)
Expand Down
1 change: 1 addition & 0 deletions svf/include/Graphs/SVFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class SVFG : public VFG
{
friend class SVFGBuilder;
friend class SaberSVFGBuilder;
friend class CFLSVFGBuilder;
friend class TaintSVFGBuilder;
friend class DDASVFGBuilder;
friend class MTASVFGBuilder;
Expand Down
4 changes: 0 additions & 4 deletions svf/include/MemoryModel/PointerAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,10 +301,6 @@ class PointerAnalysis
{
return pag->isBlkObjOrConstantObj(ptd);
}
inline bool isNonPointerObj(NodeID ptd) const
{
return pag->isNonPointerObj(ptd);
}
//@}

/// Whether this object is heap or array
Expand Down
11 changes: 11 additions & 0 deletions svf/include/SABER/ProgSlice.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ class ProgSlice
typedef FIFOWorkList<const SVFGNode*> VFWorkList; ///< worklist for value-flow guard computation
typedef FIFOWorkList<const SVFBasicBlock*> CFWorkList; ///< worklist for control-flow guard computation

typedef SaberCondAllocator::SVFGNodeToSVFGNodeSetMap SVFGNodeToSVFGNodeSetMap;


/// Constructor
ProgSlice(const SVFGNode* src, SaberCondAllocator* pa, const SVFG* graph):
root(src), partialReachable(false), fullReachable(false), reachGlob(false),
Expand Down Expand Up @@ -296,6 +299,14 @@ class ProgSlice
finalCond = cond;
}

/// Compute invalid branch condition stemming from removed strong update value-flow edges
Condition computeInvalidCondFromRemovedSUVFEdge(const SVFGNode * cur);

const SVFGNodeToSVFGNodeSetMap& getRemovedSUVFEdges() const
{
return pathAllocator->getRemovedSUVFEdges();
}

private:
SVFGNodeSet forwardslice; ///< the forward slice
SVFGNodeSet backwardslice; ///< the backward slice
Expand Down
8 changes: 8 additions & 0 deletions svf/include/SABER/SaberCondAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class SaberCondAllocator
typedef Map<const SVFFunction*, BasicBlockSet> FunToExitBBsMap; ///< map a function to all its basic blocks calling program exit
typedef Map<const SVFBasicBlock*, Condition> BBToCondMap; ///< map a basic block to its condition during control-flow guard computation
typedef FIFOWorkList<const SVFBasicBlock*> CFWorkList; ///< worklist for control-flow guard computation
typedef Map<const SVFGNode*, Set<const SVFGNode*>> SVFGNodeToSVFGNodeSetMap;


/// Constructor
Expand Down Expand Up @@ -239,6 +240,12 @@ class SaberCondAllocator
setCondInst(condition, inst);
negConds.set(condition.id());
}

SVFGNodeToSVFGNodeSetMap & getRemovedSUVFEdges()
{
return removedSUVFEdges;
}

private:

/// Allocate path condition for every basic block
Expand Down Expand Up @@ -299,6 +306,7 @@ class SaberCondAllocator
NodeBS negConds; ///bit vector for distinguish neg
std::vector<Condition> conditionVec; /// vector storing z3expression
static u32_t totalCondNum; /// a counter for fresh condition
SVFGNodeToSVFGNodeSetMap removedSUVFEdges;

protected:
BBCondMap bbConds; ///< map basic block to its successors/predecessors branch conditions
Expand Down
Loading

0 comments on commit 9de179f

Please sign in to comment.