Skip to content

Commit

Permalink
Merge pull request #1345 from jumormt/cppUtil
Browse files Browse the repository at this point in the history
cpp stage 1: move cppUtil to svf-llvm
  • Loading branch information
yuleisui authored Jan 24, 2024
2 parents 7a166bf + 91c5f70 commit ead072e
Show file tree
Hide file tree
Showing 25 changed files with 953 additions and 923 deletions.
74 changes: 74 additions & 0 deletions svf/include/Util/CppUtil.h → 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 "Util/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 "Util/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
Loading

0 comments on commit ead072e

Please sign in to comment.