Skip to content

Commit

Permalink
Merge pull request #1563 from jumormt/10.7
Browse files Browse the repository at this point in the history
remove callsite in icfgnode
  • Loading branch information
yuleisui authored Oct 9, 2024
2 parents 8c70cbe + d2fd3a9 commit 905d5fe
Show file tree
Hide file tree
Showing 9 changed files with 131 additions and 74 deletions.
52 changes: 27 additions & 25 deletions svf-llvm/lib/ICFGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
*/

#include "SVF-LLVM/ICFGBuilder.h"
#include "SVF-LLVM/CppUtil.h"
#include "SVF-LLVM/LLVMModule.h"
#include "SVF-LLVM/LLVMUtil.h"

Expand Down Expand Up @@ -239,17 +240,30 @@ InterICFGNode* ICFGBuilder::addInterBlockICFGNode(const Instruction* inst)
assert(LLVMUtil::isCallSite(inst) && "not a call instruction?");
assert(LLVMUtil::isNonInstricCallSite(inst) && "associating an intrinsic debug instruction with an ICFGNode!");
assert(llvmModuleSet()->getCallBlock(inst)==nullptr && "duplicate CallICFGNode");
CallICFGNode* callICFGNode =
new CallICFGNode(icfg->totalICFGNode++, svfInst,
llvmModuleSet()->getSVFType(inst->getType()));
icfg->addICFGNode(callICFGNode);
const CallBase* cb = SVFUtil::dyn_cast<CallBase>(inst);
bool isvcall = cppUtil::isVirtualCallSite(cb);
SVFFunction* calledFunc = nullptr;
auto called_llvmval = cb->getCalledOperand()->stripPointerCasts();
if (const Function* called_llvmfunc = SVFUtil::dyn_cast<Function>(called_llvmval))
{
calledFunc = llvmModuleSet()->getSVFFunction(called_llvmfunc);
}
else
{
calledFunc = SVFUtil::dyn_cast<SVFFunction>(
llvmModuleSet()->getSVFValue(called_llvmval));
}

CallICFGNode* callICFGNode = icfg->addCallICFGNode(
svfInst->getParent(), llvmModuleSet()->getSVFType(inst->getType()),
calledFunc, cb->getFunctionType()->isVarArg(), isvcall,
isvcall ? cppUtil::getVCallIdx(cb) : 0,
isvcall ? cppUtil::getFunNameOfVCallSite(cb) : "");
csToCallNodeMap()[inst] = callICFGNode;
llvmModuleSet()->setValueAttr(inst, callICFGNode);

assert(llvmModuleSet()->getRetBlock(inst)==nullptr && "duplicate RetICFGNode");
RetICFGNode* retICFGNode = new RetICFGNode(icfg->totalICFGNode++, svfInst, callICFGNode);
callICFGNode->setRetICFGNode(retICFGNode);
icfg->addICFGNode(retICFGNode);
RetICFGNode* retICFGNode = icfg->addRetICFGNode(callICFGNode);
csToRetNodeMap()[inst] = retICFGNode;
llvmModuleSet()->setValueAttr(inst, retICFGNode);

Expand Down Expand Up @@ -333,33 +347,21 @@ IntraICFGNode* ICFGBuilder::addIntraBlockICFGNode(const Instruction* inst)
llvmModuleSet()->getSVFInstruction(inst);
IntraICFGNode* node = llvmModuleSet()->getIntraBlock(inst);
assert (node==nullptr && "no IntraICFGNode for this instruction?");
IntraICFGNode* sNode =
new IntraICFGNode(icfg->totalICFGNode++, svfInst->getParent(),
SVFUtil::isa<ReturnInst>(inst));
icfg->addICFGNode(sNode);
IntraICFGNode* sNode = icfg->addIntraICFGNode(
svfInst->getParent(), SVFUtil::isa<ReturnInst>(inst));
instToBlockNodeMap()[inst] = sNode;
llvmModuleSet()->setValueAttr(inst, sNode);
return sNode;
}

FunEntryICFGNode* ICFGBuilder::addFunEntryBlock(const Function* fun)
{
SVFFunction* svfFunc =
llvmModuleSet()->getSVFFunction(fun);
FunEntryICFGNode* sNode = new FunEntryICFGNode(icfg->totalICFGNode++,svfFunc);
icfg->addICFGNode(sNode);
funToFunEntryNodeMap()[fun] = sNode;
icfg->FunToFunEntryNodeMap[svfFunc] = sNode;
return sNode;
return funToFunEntryNodeMap()[fun] =
icfg->addFunEntryICFGNode(llvmModuleSet()->getSVFFunction(fun));
}

inline FunExitICFGNode* ICFGBuilder::addFunExitBlock(const Function* fun)
{
SVFFunction* svfFunc =
llvmModuleSet()->getSVFFunction(fun);
FunExitICFGNode* sNode = new FunExitICFGNode(icfg->totalICFGNode++, svfFunc);
icfg->addICFGNode(sNode);
funToFunExitNodeMap()[fun] = sNode;
icfg->FunToFunExitNodeMap[svfFunc] = sNode;
return sNode;
return funToFunExitNodeMap()[fun] =
icfg->addFunExitICFGNode(llvmModuleSet()->getSVFFunction(fun));
}
5 changes: 5 additions & 0 deletions svf-llvm/lib/SVFIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -871,6 +871,11 @@ void SVFIRBuilder::visitCallSite(CallBase* cs)
if(!cs->getType()->isVoidTy())
pag->addCallSiteRets(retBlockNode,pag->getGNode(getValueNode(cs)));

if (callBlockNode->isVirtualCall())
{
const Value* value = cppUtil::getVCallVtblPtr(cs);
callBlockNode->setVtablePtr(pag->getGNode(getValueNode(value)));
}
if (const Function *callee = LLVMUtil::getCallee(cs))
{
const SVFFunction* svfcallee = llvmModuleSet()->getSVFFunction(callee);
Expand Down
39 changes: 39 additions & 0 deletions svf/include/Graphs/ICFG.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,45 @@ class ICFG : public GenericICFGTy
}
}

virtual inline IntraICFGNode* addIntraICFGNode(const SVFBasicBlock* bb, bool isRet) {
IntraICFGNode* intraIcfgNode =
new IntraICFGNode(totalICFGNode++, bb, isRet);
addICFGNode(intraIcfgNode);
return intraIcfgNode;
}

virtual inline CallICFGNode* addCallICFGNode(
const SVFBasicBlock* bb, const SVFType* ty,
const SVFFunction* calledFunc, bool isVararg, bool isvcall,
s32_t vcallIdx, const std::string& funNameOfVcall)
{

CallICFGNode* callICFGNode =
new CallICFGNode(totalICFGNode++, bb, ty, calledFunc, isVararg,
isvcall, vcallIdx, funNameOfVcall);
addICFGNode(callICFGNode);
return callICFGNode;
}

virtual inline RetICFGNode* addRetICFGNode(CallICFGNode* call) {
RetICFGNode* retICFGNode = new RetICFGNode(totalICFGNode++, call);
call->setRetICFGNode(retICFGNode);
addICFGNode(retICFGNode);
return retICFGNode;
}

virtual inline FunEntryICFGNode* addFunEntryICFGNode(const SVFFunction* svfFunc) {
FunEntryICFGNode* sNode = new FunEntryICFGNode(totalICFGNode++,svfFunc);
addICFGNode(sNode);
return FunToFunEntryNodeMap[svfFunc] = sNode;
}

virtual inline FunExitICFGNode* addFunExitICFGNode(const SVFFunction* svfFunc) {
FunExitICFGNode* sNode = new FunExitICFGNode(totalICFGNode++, svfFunc);
addICFGNode(sNode);
return FunToFunExitNodeMap[svfFunc] = sNode;
}

/// Add a ICFG node
virtual inline void addICFGNode(ICFGNode* node)
{
Expand Down
82 changes: 48 additions & 34 deletions svf/include/Graphs/ICFGNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -428,19 +428,28 @@ class CallICFGNode : public InterICFGNode
typedef std::vector<const SVFVar *> ActualParmNodeVec;

protected:
const SVFInstruction* cs;
const RetICFGNode* ret;
ActualParmNodeVec APNodes;
ActualParmNodeVec APNodes; /// arguments
const SVFFunction* calledFunc; /// called function
bool isvararg; /// is variable argument
bool isVirCallInst; /// is virtual call inst
SVFVar* vtabPtr; /// virtual table pointer
s32_t virtualFunIdx; /// virtual function index of the virtual table(s) at a virtual call
std::string funNameOfVcall; /// the function name of this virtual call

/// Constructor to create empty CallICFGNode (for SVFIRReader/deserialization)
CallICFGNode(NodeID id) : InterICFGNode(id, FunCallBlock), cs{}, ret{} {}
CallICFGNode(NodeID id) : InterICFGNode(id, FunCallBlock), ret{} {}

public:
CallICFGNode(NodeID id, const SVFInstruction* c, const SVFType* ty)
: InterICFGNode(id, FunCallBlock), cs(c), ret(nullptr)
CallICFGNode(NodeID id, const SVFBasicBlock* b, const SVFType* ty,
const SVFFunction* cf, bool iv, bool ivc, s32_t vfi,
const std::string& fnv)
: InterICFGNode(id, FunCallBlock), ret(nullptr), calledFunc(cf),
isvararg(iv), isVirCallInst(ivc), vtabPtr(nullptr),
virtualFunIdx(vfi), funNameOfVcall(fnv)
{
fun = cs->getFunction();
bb = cs->getParent();
fun = b->getFunction();
bb = b;
type = ty;
}

Expand Down Expand Up @@ -472,7 +481,7 @@ class CallICFGNode : public InterICFGNode
/// Return true if this is an indirect call
inline bool isIndirectCall() const
{
return nullptr == SVFUtil::cast<SVFCallInst>(cs)->getCalledFunction();
return nullptr == calledFunc;
}

/// Return the set of actual parameters
Expand All @@ -488,54 +497,60 @@ class CallICFGNode : public InterICFGNode
}
/// Parameter operations
//@{
const SVFVar* getArgument(u32_t ArgNo) const
inline const SVFVar* getArgument(u32_t ArgNo) const
{
return getActualParms()[ArgNo];
}

u32_t arg_size() const
inline u32_t arg_size() const
{
return APNodes.size();
}
bool arg_empty() const
inline bool arg_empty() const
{
return APNodes.empty();
}

u32_t getNumArgOperands() const
inline u32_t getNumArgOperands() const
{
return arg_size();
}
const SVFFunction* getCalledFunction() const
inline const SVFFunction* getCalledFunction() const
{
return SVFUtil::cast<SVFCallInst>(cs)->getCalledFunction();
return calledFunc;
}
const SVFValue* getCalledValue() const

inline bool isVarArg() const
{
return SVFUtil::cast<SVFCallInst>(cs)->getCalledOperand();
return isvararg;
}
bool isVarArg() const
inline bool isVirtualCall() const
{
return SVFUtil::cast<SVFCallInst>(cs)->isVarArg();
return isVirCallInst;
}
bool isVirtualCall() const
{
return SVFUtil::isa<SVFVirtualCallInst>(cs);

inline void setVtablePtr(SVFVar* v) {
vtabPtr = v;
}
const SVFValue* getVtablePtr() const

inline const SVFVar* getVtablePtr() const
{
assert(isVirtualCall() && "not a virtual call?");
return SVFUtil::cast<SVFVirtualCallInst>(cs)->getVtablePtr();
return vtabPtr;
}
s32_t getFunIdxInVtable() const


inline s32_t getFunIdxInVtable() const
{
assert(isVirtualCall() && "not a virtual call?");
return SVFUtil::cast<SVFVirtualCallInst>(cs)->getFunIdxInVtable();
assert(virtualFunIdx >=0 && "virtual function idx is less than 0? not set yet?");
return virtualFunIdx;
}
const std::string& getFunNameOfVirtualCall() const

inline const std::string& getFunNameOfVirtualCall() const
{
assert(isVirtualCall() && "not a virtual call?");
return SVFUtil::cast<SVFVirtualCallInst>(cs)->getFunNameOfVirtualCall();
return funNameOfVcall;
}
//@}

Expand Down Expand Up @@ -585,23 +600,22 @@ class RetICFGNode : public InterICFGNode
friend class SVFIRReader;

private:
const SVFInstruction* cs;
const SVFVar *actualRet;
const CallICFGNode* callBlockNode;

/// Constructor to create empty RetICFGNode (for SVFIRReader/deserialization)
RetICFGNode(NodeID id)
: InterICFGNode(id, FunRetBlock), cs{}, actualRet{}, callBlockNode{}
: InterICFGNode(id, FunRetBlock), actualRet{}, callBlockNode{}
{
}

public:
RetICFGNode(NodeID id, const SVFInstruction* c, CallICFGNode* cb) :
InterICFGNode(id, FunRetBlock), cs(c), actualRet(nullptr), callBlockNode(cb)
RetICFGNode(NodeID id, CallICFGNode* cb) :
InterICFGNode(id, FunRetBlock), actualRet(nullptr), callBlockNode(cb)
{
fun = cs->getFunction();
bb = cs->getParent();
type = callBlockNode->getType();
fun = cb->getFun();
bb = cb->getBB();
type = cb->getType();
}

inline const CallICFGNode* getCallICFGNode() const
Expand Down
7 changes: 4 additions & 3 deletions svf/lib/CFL/CFLAlias.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,10 @@ void CFLAlias::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites, Call

if (cs->isVirtualCall())
{
const SVFValue* vtbl = cs->getVtablePtr();
assert(pag->hasValueNode(vtbl));
NodeID vtblId = pag->getValueNode(vtbl);
const SVFVar* vtbl = cs->getVtablePtr();

assert(vtbl != nullptr);
NodeID vtblId = vtbl->getId();
resolveCPPIndCalls(cs, getCFLPts(vtblId), newEdges);
}
else
Expand Down
6 changes: 3 additions & 3 deletions svf/lib/DDA/DDAClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ OrderedNodeSet& FunptrDDAClient::collectCandidateQueries(SVFIR* p)
{
if (it->first->isVirtualCall())
{
const SVFValue* vtblPtr = it->first->getVtablePtr();
assert(pag->hasValueNode(vtblPtr) && "not a vtable pointer?");
NodeID vtblId = pag->getValueNode(vtblPtr);
const SVFVar* vtblPtr = it->first->getVtablePtr();
assert(vtblPtr != nullptr && "not a vtable pointer?");
NodeID vtblId = vtblPtr->getId();
addCandidate(vtblId);
vtableToCallSiteMap[vtblId] = it->first;
}
Expand Down
6 changes: 3 additions & 3 deletions svf/lib/MemoryModel/PointerAnalysisImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -497,9 +497,9 @@ void BVDataPTAImpl::onTheFlyCallGraphSolve(const CallSiteToFunPtrMap& callsites,

if (cs->isVirtualCall())
{
const SVFValue* vtbl = cs->getVtablePtr();
assert(pag->hasValueNode(vtbl));
NodeID vtblId = pag->getValueNode(vtbl);
const SVFVar* vtbl = cs->getVtablePtr();
assert(vtbl != nullptr);
NodeID vtblId = vtbl->getId();
resolveCPPIndCalls(cs, getPts(vtblId), newEdges);
}
else
Expand Down
4 changes: 0 additions & 4 deletions svf/lib/SVFIR/SVFFileSystem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,6 @@ cJSON* SVFIRWriter::contentToJson(const FunExitICFGNode* node)
cJSON* SVFIRWriter::contentToJson(const CallICFGNode* node)
{
cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
JSON_WRITE_FIELD(root, node, cs);
JSON_WRITE_FIELD(root, node, ret);
JSON_WRITE_FIELD(root, node, APNodes);
return root;
Expand All @@ -421,7 +420,6 @@ cJSON* SVFIRWriter::contentToJson(const CallICFGNode* node)
cJSON* SVFIRWriter::contentToJson(const RetICFGNode* node)
{
cJSON* root = contentToJson(static_cast<const ICFGNode*>(node));
JSON_WRITE_FIELD(root, node, cs);
JSON_WRITE_FIELD(root, node, actualRet);
JSON_WRITE_FIELD(root, node, callBlockNode);
return root;
Expand Down Expand Up @@ -2205,15 +2203,13 @@ void SVFIRReader::fill(const cJSON*& fieldJson, FunExitICFGNode* node)
void SVFIRReader::fill(const cJSON*& fieldJson, CallICFGNode* node)
{
fill(fieldJson, static_cast<ICFGNode*>(node));
JSON_READ_FIELD_FWD(fieldJson, node, cs);
JSON_READ_FIELD_FWD(fieldJson, node, ret);
JSON_READ_FIELD_FWD(fieldJson, node, APNodes);
}

void SVFIRReader::fill(const cJSON*& fieldJson, RetICFGNode* node)
{
fill(fieldJson, static_cast<ICFGNode*>(node));
JSON_READ_FIELD_FWD(fieldJson, node, cs);
JSON_READ_FIELD_FWD(fieldJson, node, actualRet);
JSON_READ_FIELD_FWD(fieldJson, node, callBlockNode);
}
Expand Down
4 changes: 2 additions & 2 deletions svf/lib/WPA/TypeAnalysis.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ void TypeAnalysis::callGraphSolveBasedOnCHA(const CallSiteToFunPtrMap& callsites
const CallICFGNode* cbn = iter->first;
if (cbn->isVirtualCall())
{
const SVFValue* vtbl = cbn->getVtablePtr();
const SVFVar* vtbl = cbn->getVtablePtr();
(void)vtbl; // Suppress warning of unused variable under release build
assert(pag->hasValueNode(vtbl));
assert(vtbl != nullptr);
VFunSet vfns;
getVFnsFromCHA(cbn, vfns);
connectVCallToVFns(cbn, vfns, newEdges);
Expand Down

0 comments on commit 905d5fe

Please sign in to comment.