Skip to content

Commit

Permalink
refactor icfgbuilder and remove svfvirtualcallinst class
Browse files Browse the repository at this point in the history
  • Loading branch information
jumormt committed Oct 21, 2024
1 parent 28ff9f4 commit a633cc8
Show file tree
Hide file tree
Showing 9 changed files with 83 additions and 148 deletions.
31 changes: 2 additions & 29 deletions svf-llvm/include/SVF-LLVM/ICFGBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,44 +58,17 @@ class ICFGBuilder
public:
typedef FIFOWorkList<const Instruction*> WorkList;

ICFGBuilder(): icfg(new ICFG())
{
ICFGBuilder() = default;

}
ICFG* build();

private:

LLVMModuleSet* llvmModuleSet()
inline LLVMModuleSet* llvmModuleSet()
{
return LLVMModuleSet::getLLVMModuleSet();
}

CSToRetNodeMapTy& csToRetNodeMap()
{
return llvmModuleSet()->CSToRetNodeMap;
}

CSToCallNodeMapTy& csToCallNodeMap()
{
return llvmModuleSet()->CSToCallNodeMap;
}

InstToBlockNodeMapTy& instToBlockNodeMap()
{
return llvmModuleSet()->InstToBlockNodeMap;
}

FunToFunEntryNodeMapTy& funToFunEntryNodeMap()
{
return llvmModuleSet()->FunToFunEntryNodeMap;
}

FunToFunExitNodeMapTy& funToFunExitNodeMap()
{
return llvmModuleSet()->FunToFunExitNodeMap;
}

private:

/// Create edges between ICFG nodes within a function
Expand Down
32 changes: 32 additions & 0 deletions svf-llvm/include/SVF-LLVM/LLVMModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class LLVMModuleSet
typedef Map<const GlobalVariable*, GlobalVariable*> GlobalDefToRepMapTy;

typedef Map<const Function*, SVFFunction*> LLVMFun2SVFFunMap;
typedef Map<const Function*, CallGraphNode*> LLVMFun2CallGraphNodeMap;
typedef Map<const BasicBlock*, SVFBasicBlock*> LLVMBB2SVFBBMap;
typedef Map<const Instruction*, SVFInstruction*> LLVMInst2SVFInstMap;
typedef Map<const Argument*, SVFArgument*> LLVMArgument2SVFArgumentMap;
Expand Down Expand Up @@ -89,6 +90,7 @@ class LLVMModuleSet
GlobalDefToRepMapTy GlobalDefToRepMap;

LLVMFun2SVFFunMap LLVMFunc2SVFFunc; ///< Map an LLVM Function to an SVF Function
LLVMFun2CallGraphNodeMap LLVMFun2CallGraphNode; ///< Map an LLVM Function to a callgraph node
LLVMBB2SVFBBMap LLVMBB2SVFBB;
LLVMInst2SVFInstMap LLVMInst2SVFInst;
LLVMArgument2SVFArgumentMap LLVMArgument2SVFArgument;
Expand Down Expand Up @@ -170,6 +172,11 @@ class LLVMModuleSet
LLVMFunc2SVFFunc[func] = svfFunc;
setValueAttr(func,svfFunc);
}
inline void addFunctionMap(const Function* func, CallGraphNode* svfFunc)
{
LLVMFun2CallGraphNode[func] = svfFunc;
setValueAttr(func,svfFunc);
}
inline void addBasicBlockMap(const BasicBlock* bb, SVFBasicBlock* svfBB)
{
LLVMBB2SVFBB[bb] = svfBB;
Expand All @@ -180,6 +187,22 @@ class LLVMModuleSet
LLVMInst2SVFInst[inst] = svfInst;
setValueAttr(inst,svfInst);
}
inline void addInstructionMap(const Instruction* inst, CallICFGNode* svfInst)
{
CSToCallNodeMap[inst] = svfInst;
setValueAttr(inst,svfInst);
}
inline void addInstructionMap(const Instruction* inst, RetICFGNode* svfInst)
{
CSToRetNodeMap[inst] = svfInst;
setValueAttr(inst,svfInst);
}
inline void addInstructionMap(const Instruction* inst, IntraICFGNode* svfInst)
{
InstToBlockNodeMap[inst] = svfInst;
setValueAttr(inst,svfInst);
}

inline void addArgumentMap(const Argument* arg, SVFArgument* svfArg)
{
LLVMArgument2SVFArgument[arg] = svfArg;
Expand Down Expand Up @@ -213,6 +236,8 @@ class LLVMModuleSet

SVFValue* getSVFValue(const Value* value);

SVFBaseNode* getSVFBaseNode(const Value* value);

const Value* getLLVMValue(const SVFValue* value) const
{
SVFValue2LLVMValueMap::const_iterator it = SVFValue2LLVMValue.find(value);
Expand All @@ -227,6 +252,13 @@ class LLVMModuleSet
return it->second;
}

inline CallGraphNode* getCallGraphNode(const Function* fun) const
{
LLVMFun2CallGraphNodeMap::const_iterator it = LLVMFun2CallGraphNode.find(fun);
assert(it!=LLVMFun2CallGraphNode.end() && "SVF Function not found!");
return it->second;
}

inline SVFFunction* getSVFFunction(const Function* fun) const
{
LLVMFun2SVFFunMap::const_iterator it = LLVMFunc2SVFFunc.find(fun);
Expand Down
2 changes: 2 additions & 0 deletions svf-llvm/include/SVF-LLVM/SVFIRBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ class SVFIRBuilder: public llvm::InstVisitor<SVFIRBuilder>
return pag;
}

void setMemObjValueAttr();

/// Initialize nodes and edges
//@{
void initialiseNodes();
Expand Down
14 changes: 6 additions & 8 deletions svf-llvm/lib/ICFGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ using namespace SVFUtil;
*/
ICFG* ICFGBuilder::build()
{
icfg = new ICFG();
DBOUT(DGENERAL, outs() << pasMsg("\t Building ICFG ...\n"));
// Add the unique global ICFGNode at the entry of a program (before the main method).
addGlobalICFGNode();
Expand Down Expand Up @@ -260,13 +261,11 @@ InterICFGNode* ICFGBuilder::addInterBlockICFGNode(const Instruction* inst)
calledFunc, cb->getFunctionType()->isVarArg(), isvcall,
isvcall ? cppUtil::getVCallIdx(cb) : 0,
isvcall ? cppUtil::getFunNameOfVCallSite(cb) : "");
csToCallNodeMap()[inst] = callICFGNode;
llvmModuleSet()->setValueAttr(inst, callICFGNode);
llvmModuleSet()->addInstructionMap(inst, callICFGNode);

assert(llvmModuleSet()->getRetBlock(inst)==nullptr && "duplicate RetICFGNode");
RetICFGNode* retICFGNode = icfg->addRetICFGNode(callICFGNode);
csToRetNodeMap()[inst] = retICFGNode;
llvmModuleSet()->setValueAttr(inst, retICFGNode);
llvmModuleSet()->addInstructionMap(inst, retICFGNode);

addICFGInterEdges(inst, LLVMUtil::getCallee(SVFUtil::cast<CallBase>(inst))); //creating interprocedural edges
return callICFGNode;
Expand Down Expand Up @@ -347,19 +346,18 @@ IntraICFGNode* ICFGBuilder::addIntraBlockICFGNode(const Instruction* inst)
assert (node==nullptr && "no IntraICFGNode for this instruction?");
IntraICFGNode* sNode = icfg->addIntraICFGNode(
llvmModuleSet()->getSVFBasicBlock(inst->getParent()), SVFUtil::isa<ReturnInst>(inst));
instToBlockNodeMap()[inst] = sNode;
llvmModuleSet()->setValueAttr(inst, sNode);
llvmModuleSet()->addInstructionMap(inst, sNode);
return sNode;
}

FunEntryICFGNode* ICFGBuilder::addFunEntryBlock(const Function* fun)
{
return funToFunEntryNodeMap()[fun] =
return llvmModuleSet()->FunToFunEntryNodeMap[fun] =
icfg->addFunEntryICFGNode(llvmModuleSet()->getSVFFunction(fun));
}

inline FunExitICFGNode* ICFGBuilder::addFunExitBlock(const Function* fun)
{
return funToFunExitNodeMap()[fun] =
return llvmModuleSet()->FunToFunExitNodeMap[fun] =
icfg->addFunExitICFGNode(llvmModuleSet()->getSVFFunction(fun));
}
38 changes: 25 additions & 13 deletions svf-llvm/lib/LLVMModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,12 @@ void LLVMModuleSet::build()

CallGraphBuilder callGraphBuilder;
callgraph = callGraphBuilder.buildSVFIRCallGraph(svfModule);

for (const auto& func : svfModule->getFunctionSet())
{
addFunctionMap(SVFUtil::cast<Function>(getLLVMValue(func)),
callgraph->getCallGraphNode(func));
}
}

void LLVMModuleSet::createSVFDataStructure()
Expand Down Expand Up @@ -284,13 +290,7 @@ void LLVMModuleSet::createSVFFunction(const Function* func)
SVFInstruction* svfInst = nullptr;
if (const CallBase* call = SVFUtil::dyn_cast<CallBase>(&inst))
{
if (cppUtil::isVirtualCallSite(call))
svfInst = new SVFVirtualCallInst(
getSVFType(call->getType()), svfBB,
call->getFunctionType()->isVarArg(),
inst.isTerminator());
else
svfInst = new SVFCallInst(
svfInst = new SVFCallInst(
getSVFType(call->getType()), svfBB,
call->getFunctionType()->isVarArg(),
inst.isTerminator());
Expand Down Expand Up @@ -373,12 +373,6 @@ void LLVMModuleSet::initSVFBasicBlock(const Function* func)
{
svfcall->setCalledOperand(getSVFValue(called_llvmval));
}
if(SVFVirtualCallInst* virtualCall = SVFUtil::dyn_cast<SVFVirtualCallInst>(svfcall))
{
virtualCall->setVtablePtr(getSVFValue(cppUtil::getVCallVtblPtr(call)));
virtualCall->setFunIdxInVtable(cppUtil::getVCallIdx(call));
virtualCall->setFunNameOfVirtualCall(cppUtil::getFunNameOfVCallSite(call));
}
for(u32_t i = 0; i < call->arg_size(); i++)
{
SVFValue* svfval = getSVFValue(call->getArgOperand(i));
Expand Down Expand Up @@ -1367,6 +1361,24 @@ SVFValue* LLVMModuleSet::getSVFValue(const Value* value)
return getSVFOtherValue(value);
}

SVFBaseNode* LLVMModuleSet::getSVFBaseNode(const Value* value)
{
if (const Instruction* inst = SVFUtil::dyn_cast<Instruction>(value))
{
if(!LLVMUtil::isIntrinsicInst(inst))
return getICFGNode(inst);
}
else if (const Function* func = SVFUtil::dyn_cast<Function>(value))
{
return getCallGraphNode(func);
}
else
{
// TODO: add more llvm value to svfbase node map
}
return nullptr;
}

const Type* LLVMModuleSet::getLLVMType(const SVFType* T) const
{
for(LLVMType2SVFTypeMap::const_iterator it = LLVMType2SVFType.begin(), eit = LLVMType2SVFType.end(); it!=eit; ++it)
Expand Down
30 changes: 16 additions & 14 deletions svf-llvm/lib/SVFIRBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,6 @@ SVFIR* SVFIRBuilder::build()
// Set callgraph
pag->setCallGraph(llvmModuleSet()->callgraph);

// Set icfgnode in memobj
for (auto& it : SymbolTableInfo::SymbolInfo()->idToObjMap())
{
if(!it.second->getValue())
continue;
if (const Instruction* inst =
SVFUtil::dyn_cast<Instruction>(llvmModuleSet()->getLLVMValue(
it.second->getValue())))
{
if(llvmModuleSet()->hasICFGNode(inst))
it.second->gNode = llvmModuleSet()->getICFGNode(inst);
}
}

CHGraph* chg = new CHGraph(pag->getModule());
CHGBuilder chgbuilder(chg);
chgbuilder.buildCHG();
Expand All @@ -104,6 +90,10 @@ SVFIR* SVFIRBuilder::build()
visitGlobal(svfModule);
///// collect exception vals in the program


/// set memobj value attributes
setMemObjValueAttr();

/// handle functions
for (Module& M : llvmModuleSet()->getLLVMModules())
{
Expand Down Expand Up @@ -194,6 +184,18 @@ SVFIR* SVFIRBuilder::build()
return pag;
}

void SVFIRBuilder::setMemObjValueAttr()
{
// Set icfgnode in memobj
for (auto& it : SymbolTableInfo::SymbolInfo()->idToObjMap())
{
if(!it.second->getValue())
continue;
it.second->gNode = llvmModuleSet()->getSVFBaseNode(
llvmModuleSet()->getLLVMValue(it.second->getValue()));
}
}

/*
* Initial all the nodes from symbol table
*/
Expand Down
3 changes: 0 additions & 3 deletions svf/include/SVFIR/SVFFileSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ class SVFFunction;
class SVFBasicBlock;
class SVFInstruction;
class SVFCallInst;
class SVFVirtualCallInst;
class SVFConstant;
class SVFGlobalValue;
class SVFArgument;
Expand Down Expand Up @@ -516,7 +515,6 @@ class SVFIRWriter
cJSON* contentToJson(const SVFBasicBlock* value);
cJSON* contentToJson(const SVFInstruction* value);
cJSON* contentToJson(const SVFCallInst* value);
cJSON* contentToJson(const SVFVirtualCallInst* value);
cJSON* contentToJson(const SVFConstant* value);
cJSON* contentToJson(const SVFGlobalValue* value);
cJSON* contentToJson(const SVFArgument* value);
Expand Down Expand Up @@ -1290,7 +1288,6 @@ class SVFIRReader
void fill(const cJSON*& fieldJson, SVFBasicBlock* value);
void fill(const cJSON*& fieldJson, SVFInstruction* value);
void fill(const cJSON*& fieldJson, SVFCallInst* value);
void fill(const cJSON*& fieldJson, SVFVirtualCallInst* value);
void fill(const cJSON*& fieldJson, SVFConstant* value);
void fill(const cJSON*& fieldJson, SVFGlobalValue* value);
void fill(const cJSON*& fieldJson, SVFArgument* value);
Expand Down
60 changes: 0 additions & 60 deletions svf/include/SVFIR/SVFValue.h
Original file line number Diff line number Diff line change
Expand Up @@ -735,66 +735,6 @@ class SVFCallInst : public SVFInstruction
}
};

class SVFVirtualCallInst : public SVFCallInst
{
friend class SVFIRWriter;
friend class SVFIRReader;
friend class LLVMModuleSet;

private:
const SVFValue* vCallVtblPtr; /// 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

protected:
inline void setFunIdxInVtable(s32_t idx)
{
virtualFunIdx = idx;
}
inline void setFunNameOfVirtualCall(const std::string& name)
{
funNameOfVcall = name;
}
inline void setVtablePtr(const SVFValue* vptr)
{
vCallVtblPtr = vptr;
}

public:
SVFVirtualCallInst(const SVFType* ty, const SVFBasicBlock* b, bool vararg,
bool tm)
: SVFCallInst(ty, b, vararg, tm, SVFVCall), vCallVtblPtr(nullptr),
virtualFunIdx(-1), funNameOfVcall()
{
}
inline const SVFValue* getVtablePtr() const
{
assert(vCallVtblPtr && "virtual call does not have a vtblptr? set it first");
return vCallVtblPtr;
}
inline s32_t getFunIdxInVtable() const
{
assert(virtualFunIdx >=0 && "virtual function idx is less than 0? not set yet?");
return virtualFunIdx;
}
inline const std::string& getFunNameOfVirtualCall() const
{
return funNameOfVcall;
}
static inline bool classof(const SVFValue *node)
{
return node->getKind() == SVFVCall;
}
static inline bool classof(const SVFInstruction *node)
{
return node->getKind() == SVFVCall;
}
static inline bool classof(const SVFCallInst *node)
{
return node->getKind() == SVFVCall;
}
};

class SVFConstant : public SVFValue
{
friend class SVFIRWriter;
Expand Down
Loading

0 comments on commit a633cc8

Please sign in to comment.