Skip to content

Commit

Permalink
move cpp API to cppUtil
Browse files Browse the repository at this point in the history
  • Loading branch information
jumormt committed Jan 24, 2024
1 parent babeb11 commit 91c5f70
Show file tree
Hide file tree
Showing 18 changed files with 701 additions and 674 deletions.
74 changes: 74 additions & 0 deletions svf-llvm/include/SVF-LLVM/CppUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#define CPPUtil_H_

#include "SVFIR/SVFValue.h"
#include "SVF-LLVM/BasicTypes.h"

namespace SVF
{
Expand All @@ -55,6 +56,79 @@ struct DemangledName demangle(const std::string& name);
std::string getBeforeBrackets(const std::string& name);
std::string getClassNameFromVtblObj(const std::string& vtblName);

/*
* Get the vtable struct of a class.
*
* Given the class:
*
* class A {
* virtual ~A();
* };
* A::~A() = default;
*
* The corresponding vtable @_ZTV1A is of type:
*
* { [4 x i8*] }
*
* If the program has been compiled with AddressSanitizer,
* the vtable will have redzones and appear as:
*
* { { [4 x i8*] }, [32 x i8] }
*
* See https://github.com/SVF-tools/SVF/issues/1114 for more.
*/
const ConstantStruct *getVtblStruct(const GlobalValue *vtbl);

bool isValVtbl(const Value* val);
bool isVirtualCallSite(const CallBase* cs);
bool isConstructor(const Function* F);
bool isDestructor(const Function* F);
bool isCPPThunkFunction(const Function* F);
const Function* getThunkTarget(const Function* F);

/*
* VtableA = {&A::foo}
* A::A(this){
* *this = &VtableA;
* }
*
*
* A* p = new A;
* cs: p->foo(...)
* ==>
* vtptr = *p;
* vfn = &vtptr[i]
* %funp = *vfn
* call %funp(p,...)
* getConstructorThisPtr(A) return "this" pointer
* getVCallThisPtr(cs) return p (this pointer)
* getVCallVtblPtr(cs) return vtptr
* getVCallIdx(cs) return i
* getClassNameFromVtblObj(VtableA) return
* getClassNameFromType(type of p) return type A
*/
const Argument* getConstructorThisPtr(const Function* fun);
const Value* getVCallThisPtr(const CallBase* cs);
const Value* getVCallVtblPtr(const CallBase* cs);
s32_t getVCallIdx(const CallBase* cs);
bool classTyHasVTable(const StructType* ty);
std::string getClassNameFromType(const StructType* ty);
std::string getClassNameOfThisPtr(const CallBase* cs);
std::string getFunNameOfVCallSite(const CallBase* cs);
bool VCallInCtorOrDtor(const CallBase* cs);

/*
* A(A* this){
* store this this.addr;
* tmp = load this.addr;
* this1 = bitcast(tmp);
* B(this1);
* }
* this and this1 are the same thisPtr in the constructor
*/
bool isSameThisPtrInConstructor(const Argument* thisPtr1,
const Value* thisPtr2);

/// Constants pertaining to CTir, for C and C++.
/// TODO: move helper functions here too?
namespace ctir
Expand Down
10 changes: 1 addition & 9 deletions svf-llvm/include/SVF-LLVM/DCHG.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

#include "Graphs/GenericGraph.h"
#include "Graphs/CHG.h"
#include "SVF-LLVM/CppUtil.h"
#include "SVF-LLVM/BasicTypes.h"
#include "SVFIR/SVFModule.h"
#include "Util/SVFUtil.h"
Expand Down Expand Up @@ -413,14 +412,7 @@ class DCHGraph : public CommonCHGraph, public GenericGraph<DCHNode, DCHEdge>
DCHNode* getOrCreateNode(const DIType* type);

/// Retrieves the metadata associated with a *virtual* callsite.
const DIType* getCSStaticType(CallBase* cs) const
{
MDNode *md = cs->getMetadata(cppUtil::ctir::derefMDName);
assert(md != nullptr && "Missing type metadata at virtual callsite");
DIType *diType = SVFUtil::dyn_cast<DIType>(md);
assert(diType != nullptr && "Incorrect metadata type at virtual callsite");
return diType;
}
const DIType* getCSStaticType(CallBase* cs) const;

const DIType *getCSStaticType(CallSite cs) const
{
Expand Down
1 change: 1 addition & 0 deletions svf-llvm/include/SVF-LLVM/ICFGBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@

#include "Graphs/ICFG.h"
#include "Util/WorkList.h"
#include "BasicTypes.h"

namespace SVF
{
Expand Down
1 change: 0 additions & 1 deletion svf-llvm/include/SVF-LLVM/LLVMModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
#define INCLUDE_SVF_FE_LLVMMODULE_H_

#include "SVF-LLVM/BasicTypes.h"
#include "SVF-LLVM/CppUtil.h"
#include "SVFIR/SVFValue.h"
#include "SVFIR/SVFModule.h"
#include "Util/Options.h"
Expand Down
112 changes: 4 additions & 108 deletions svf-llvm/include/SVF-LLVM/LLVMUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@

#include "Util/SVFUtil.h"
#include "SVF-LLVM/BasicTypes.h"
#include "SVF-LLVM/LLVMModule.h"
#include "SVFIR/SVFValue.h"
#include "Util/ThreadAPI.h"

Expand All @@ -54,15 +53,7 @@ inline bool isCallSite(const Value* val)
}

/// Get the definition of a function across multiple modules
inline const Function* getDefFunForMultipleModule(const Function* fun)
{
if (fun == nullptr)
return nullptr;
LLVMModuleSet* llvmModuleset = LLVMModuleSet::getLLVMModuleSet();
if (fun->isDeclaration() && llvmModuleset->hasDefinition(fun))
fun = LLVMModuleSet::getLLVMModuleSet()->getDefinition(fun);
return fun;
}
const Function* getDefFunForMultipleModule(const Function* fun);

/// Return LLVM callsite given a value
inline const CallBase* getLLVMCallSite(const Value* value)
Expand All @@ -85,18 +76,7 @@ inline const Function* getLLVMFunction(const Value* val)
}

/// Get program entry function from module.
inline const Function* getProgFunction(const std::string& funName)
{
for (const Module& M : LLVMModuleSet::getLLVMModuleSet()->getLLVMModules())
{
for (const Function& fun : M)
{
if (fun.getName() == funName)
return &fun;
}
}
return nullptr;
}
const Function* getProgFunction(const std::string& funName);

/// Check whether a function is an entry function (i.e., main)
inline bool isProgEntryFunction(const Function* fun)
Expand Down Expand Up @@ -354,10 +334,7 @@ void removeUnusedGlobalVariables(Module* module);
void removeUnusedFuncsAndAnnotationsAndGlobalVariables(std::vector<Function*> removedFuncList);

/// Get the corresponding Function based on its name
inline const SVFFunction* getFunction(const std::string& name)
{
return LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(name);
}
const SVFFunction* getFunction(const std::string& name);

/// Return true if the value refers to constant data, e.g., i32 0
inline bool isConstDataOrAggData(const Value* val)
Expand All @@ -367,15 +344,7 @@ inline bool isConstDataOrAggData(const Value* val)
}

/// find the unique defined global across multiple modules
inline const Value* getGlobalRep(const Value* val)
{
if (const GlobalVariable* gvar = SVFUtil::dyn_cast<GlobalVariable>(val))
{
if (LLVMModuleSet::getLLVMModuleSet()->hasGlobalRep(gvar))
val = LLVMModuleSet::getLLVMModuleSet()->getGlobalRep(gvar);
}
return val;
}
const Value* getGlobalRep(const Value* val);

/// Check whether this value points-to a constant object
bool isConstantObjSym(const SVFValue* val);
Expand All @@ -389,79 +358,6 @@ void viewCFG(const Function* fun);
// Dump Control Flow Graph of llvm function, without instructions
void viewCFGOnly(const Function* fun);

/*
* Get the vtable struct of a class.
*
* Given the class:
*
* class A {
* virtual ~A();
* };
* A::~A() = default;
*
* The corresponding vtable @_ZTV1A is of type:
*
* { [4 x i8*] }
*
* If the program has been compiled with AddressSanitizer,
* the vtable will have redzones and appear as:
*
* { { [4 x i8*] }, [32 x i8] }
*
* See https://github.com/SVF-tools/SVF/issues/1114 for more.
*/
const ConstantStruct *getVtblStruct(const GlobalValue *vtbl);

bool isValVtbl(const Value* val);
bool isVirtualCallSite(const CallBase* cs);
bool isConstructor(const Function* F);
bool isDestructor(const Function* F);
bool isCPPThunkFunction(const Function* F);
const Function* getThunkTarget(const Function* F);

/*
* VtableA = {&A::foo}
* A::A(this){
* *this = &VtableA;
* }
*
*
* A* p = new A;
* cs: p->foo(...)
* ==>
* vtptr = *p;
* vfn = &vtptr[i]
* %funp = *vfn
* call %funp(p,...)
* getConstructorThisPtr(A) return "this" pointer
* getVCallThisPtr(cs) return p (this pointer)
* getVCallVtblPtr(cs) return vtptr
* getVCallIdx(cs) return i
* getClassNameFromVtblObj(VtableA) return
* getClassNameFromType(type of p) return type A
*/
const Argument* getConstructorThisPtr(const Function* fun);
const Value* getVCallThisPtr(const CallBase* cs);
const Value* getVCallVtblPtr(const CallBase* cs);
s32_t getVCallIdx(const CallBase* cs);
bool classTyHasVTable(const StructType* ty);
std::string getClassNameFromType(const StructType* ty);
std::string getClassNameOfThisPtr(const CallBase* cs);
std::string getFunNameOfVCallSite(const CallBase* cs);
bool VCallInCtorOrDtor(const CallBase* cs);

/*
* A(A* this){
* store this this.addr;
* tmp = load this.addr;
* this1 = bitcast(tmp);
* B(this1);
* }
* this and this1 are the same thisPtr in the constructor
*/
bool isSameThisPtrInConstructor(const Argument* thisPtr1,
const Value* thisPtr2);

std::string dumpValue(const Value* val);

std::string dumpType(const Type* type);
Expand Down
23 changes: 12 additions & 11 deletions svf-llvm/lib/CHGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "SVF-LLVM/LLVMUtil.h"
#include "SVFIR/SVFModule.h"
#include "Util/PTAStat.h"
#include "SVF-LLVM/LLVMModule.h"

using namespace SVF;
using namespace SVFUtil;
Expand Down Expand Up @@ -88,9 +89,9 @@ void CHGBuilder::buildCHG()

void CHGBuilder::buildCHGNodes(const GlobalValue *globalvalue)
{
if (LLVMUtil::isValVtbl(globalvalue) && globalvalue->getNumOperands() > 0)
if (cppUtil::isValVtbl(globalvalue) && globalvalue->getNumOperands() > 0)
{
const ConstantStruct *vtblStruct = LLVMUtil::getVtblStruct(globalvalue);
const ConstantStruct *vtblStruct = cppUtil::getVtblStruct(globalvalue);
string className = getClassNameFromVtblObj(globalvalue->getName().str());
if (!chg->getNode(className))
createNode(className);
Expand Down Expand Up @@ -168,7 +169,7 @@ void CHGBuilder::connectInheritEdgeViaCall(const Function* caller, const CallBas
{
if (cs->arg_size() < 1 || (cs->arg_size() < 2 && cs->paramHasAttr(0, llvm::Attribute::StructRet)))
return;
const Value* csThisPtr = LLVMUtil::getVCallThisPtr(cs);
const Value* csThisPtr = cppUtil::getVCallThisPtr(cs);
//const Argument* consThisPtr = getConstructorThisPtr(caller);
//bool samePtr = isSameThisPtrInConstructor(consThisPtr, csThisPtr);
bool samePtrTrue = true;
Expand Down Expand Up @@ -197,7 +198,7 @@ void CHGBuilder::connectInheritEdgeViaStore(const Function* caller, const StoreI
if (bcce->getOpcode() == Instruction::GetElementPtr)
{
const Value* gepval = bcce->getOperand(0);
if (LLVMUtil::isValVtbl(gepval))
if (cppUtil::isValVtbl(gepval))

Check warning on line 201 in svf-llvm/lib/CHGBuilder.cpp

View check run for this annotation

Codecov / codecov/patch

svf-llvm/lib/CHGBuilder.cpp#L201

Added line #L201 was not covered by tests
{
string vtblClassName = getClassNameFromVtblObj(gepval->getName().str());
if (vtblClassName.size() > 0 && dname.className.compare(vtblClassName) != 0)
Expand Down Expand Up @@ -364,9 +365,9 @@ void CHGBuilder::analyzeVTables(const Module &M)
E = M.global_end(); I != E; ++I)
{
const GlobalValue *globalvalue = SVFUtil::dyn_cast<const GlobalValue>(&(*I));
if (LLVMUtil::isValVtbl(globalvalue) && globalvalue->getNumOperands() > 0)
if (cppUtil::isValVtbl(globalvalue) && globalvalue->getNumOperands() > 0)
{
const ConstantStruct *vtblStruct = LLVMUtil::getVtblStruct(globalvalue);
const ConstantStruct *vtblStruct = cppUtil::getVtblStruct(globalvalue);

string vtblClassName = getClassNameFromVtblObj(globalvalue->getName().str());
CHNode *node = chg->getNode(vtblClassName);
Expand Down Expand Up @@ -641,7 +642,7 @@ void CHGBuilder::buildCSToCHAVtblsAndVfnsMap()
{
if(const CallBase* callInst = SVFUtil::dyn_cast<CallBase>(&*II))
{
if (LLVMUtil::isVirtualCallSite(callInst) == false)
if (cppUtil::isVirtualCallSite(callInst) == false)
continue;

VTableSet vtbls;
Expand Down Expand Up @@ -672,7 +673,7 @@ void CHGBuilder::buildCSToCHAVtblsAndVfnsMap()

const CHGraph::CHNodeSetTy& CHGBuilder::getCSClasses(const CallBase* cs)
{
assert(LLVMUtil::isVirtualCallSite(cs) && "not virtual callsite!");
assert(cppUtil::isVirtualCallSite(cs) && "not virtual callsite!");
const SVFInstruction* svfcall = LLVMModuleSet::getLLVMModuleSet()->getSVFInstruction(cs);

CHGraph::CallSiteToCHNodesMap::const_iterator it = chg->csToClassesMap.find(svfcall);
Expand All @@ -682,7 +683,7 @@ const CHGraph::CHNodeSetTy& CHGBuilder::getCSClasses(const CallBase* cs)
}
else
{
string thisPtrClassName = LLVMUtil::getClassNameOfThisPtr(cs);
string thisPtrClassName = cppUtil::getClassNameOfThisPtr(cs);
if (const CHNode* thisNode = chg->getNode(thisPtrClassName))
{
const CHGraph::CHNodeSetTy& instAndDesces = getInstancesAndDescendants(thisPtrClassName);
Expand All @@ -696,9 +697,9 @@ const CHGraph::CHNodeSetTy& CHGBuilder::getCSClasses(const CallBase* cs)

void CHGBuilder::addFuncToFuncVector(CHNode::FuncVector &v, const Function *lf)
{
if (LLVMUtil::isCPPThunkFunction(lf))
if (cppUtil::isCPPThunkFunction(lf))
{
if (const auto* tf = LLVMUtil::getThunkTarget(lf))
if (const auto* tf = cppUtil::getThunkTarget(lf))

Check warning on line 702 in svf-llvm/lib/CHGBuilder.cpp

View check run for this annotation

Codecov / codecov/patch

svf-llvm/lib/CHGBuilder.cpp#L702

Added line #L702 was not covered by tests
{
SVFFunction* pFunction =
LLVMModuleSet::getLLVMModuleSet()->getSVFFunction(tf);
Expand Down
Loading

0 comments on commit 91c5f70

Please sign in to comment.