Skip to content

Commit

Permalink
Opaque (#1352)
Browse files Browse the repository at this point in the history
* use auto for dyn cast

* add necessary functions for c++ class name inference

* infer class name

* refactor and add comments

* cppconstructor

* svf tools test-suite

* add comments

* refactor
  • Loading branch information
jumormt committed Jan 30, 2024
1 parent ade5d0b commit 86dee72
Show file tree
Hide file tree
Showing 7 changed files with 684 additions and 296 deletions.
1 change: 1 addition & 0 deletions svf-llvm/include/SVF-LLVM/BasicTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@
#include <llvm/BinaryFormat/Dwarf.h> // for dwarf tags

#include <llvm/Analysis/LoopInfo.h>
#include <llvm/Demangle/Demangle.h>

namespace SVF
{
Expand Down
32 changes: 31 additions & 1 deletion svf-llvm/include/SVF-LLVM/CppUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ 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);
Set<std::string> getClassNameOfThisPtr(const CallBase* cs);
std::string getFunNameOfVCallSite(const CallBase* cs);
bool VCallInCtorOrDtor(const CallBase* cs);

Expand All @@ -129,6 +129,36 @@ bool VCallInCtorOrDtor(const CallBase* cs);
bool isSameThisPtrInConstructor(const Argument* thisPtr1,
const Value* thisPtr2);

/// extract class name from the c++ function name, e.g., constructor/destructors
Set<std::string> extractClsNamesFromFunc(const Function *foo);

/// extract class names from template functions
Set<std::string> extractClsNamesFromTemplate(const std::string &oname);

/// class sources can be heap allocation
/// or functions where we can extract the class name (constructors/destructors or template functions)
bool isClsNameSource(const Value *val);

/// whether foo matches the mangler label
bool matchesLabel(const std::string &foo, const std::string &label);

/// whether foo is a cpp template function
bool isTemplateFunc(const Function *foo);

/// whether foo is a cpp dyncast function
bool isDynCast(const Function *foo);

/// whether foo is a cpp heap allocation (new)
bool isNewAlloc(const Function *foo);

/// extract class name from cpp dyncast function
std::string extractClsNameFromDynCast(const CallBase* callBase);

const Type *cppClsNameToType(const std::string &className);

std::string typeToClsName(const Type *ty);


/// Constants pertaining to CTir, for C and C++.
/// TODO: move helper functions here too?
namespace ctir
Expand Down
4 changes: 3 additions & 1 deletion svf-llvm/include/SVF-LLVM/LLVMUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,9 +100,11 @@ static inline Type* getPtrElementType(const PointerType* pty)
{
#if (LLVM_VERSION_MAJOR < 14)
return pty->getPointerElementType();
#else
#elif (LLVM_VERSION_MAJOR < 17)
assert(!pty->isOpaque() && "Opaque Pointer is used, please recompile the source adding '-Xclang -no-opaque-pointers'");
return pty->getNonOpaquePointerElementType();
#else
assert(false && "llvm version 17+ only support opaque pointers!");
#endif
}

Expand Down
54 changes: 34 additions & 20 deletions svf-llvm/include/SVF-LLVM/ObjTypeInference.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@
#include "SVFIR/SVFValue.h"
#include "Util/ThreadAPI.h"

namespace SVF
{
class ObjTypeInference
{
namespace SVF {
class ObjTypeInference {

public:
typedef Set<const Value *> ValueSet;
Expand All @@ -47,12 +45,17 @@ class ObjTypeInference
typedef ValueToValueSet ValueToSources;
typedef Map<const Value *, const Type *> ValueToType;
typedef std::pair<const Value *, bool> ValueBoolPair;
typedef Map<const Value *, Set<std::string>> ValueToClassNames;
typedef Map<const CallBase *, Set<const Function *>> AllocToClsNameSources;


private:
ValueToInferSites _valueToInferSites; // value inference site cache
ValueToType _valueToType; // value type cache
ValueToSources _valueToAllocs; // value allocations (stack, static, heap) cache
ValueToClassNames _thisPtrClassNames; // thisptr class name cache
ValueToSources _valueToAllocOrClsNameSources; // value alloc/clsname sources cache
AllocToClsNameSources _allocToClsNameSources; // alloc clsname sources cache


public:
Expand All @@ -62,49 +65,60 @@ class ObjTypeInference
~ObjTypeInference() = default;


/// get or infer the type of a value
const Type *inferObjType(const Value *startValue);
/// get or infer the type of the object pointed by the value
const Type *inferObjType(const Value *var);

/// Validate type inference
/// validate type inference
void validateTypeCheck(const CallBase *cs);

void typeSizeDiffTest(const PointerType *oPTy, const Type *iTy, const Value *val);

/// Default type
/// default type
const Type *defaultType(const Value *val);

/// Pointer type
inline const Type *ptrType()
{
/// pointer type
inline const Type *ptrType() {
return PointerType::getUnqual(getLLVMCtx());
}

/// Int8 type
inline const IntegerType *int8Type()
{
/// int8 type
inline const IntegerType *int8Type() {
return Type::getInt8Ty(getLLVMCtx());
}

LLVMContext &getLLVMCtx();

private:

/// Forward collect all possible infer sites starting from a value
const Type *fwInferObjType(const Value *startValue);
/// forward infer the type of the object pointed by var
const Type *fwInferObjType(const Value *var);

/// Backward collect all possible allocation sites (stack, static, heap) starting from a value
Set<const Value *> bwfindAllocations(const Value *startValue);
/// backward collect all possible allocation sites (stack, static, heap) of var
Set<const Value *>& bwfindAllocOfVar(const Value *var);

bool isAllocation(const Value *val);
/// is allocation (stack, static, heap)
bool isAlloc(const SVF::Value *val);

public:
/// Select the largest (conservative) type from all types
/// select the largest (conservative) type from all types
const Type *selectLargestSizedType(Set<const Type *> &objTys);

u32_t objTyToNumFields(const Type *objTy);

u32_t getArgPosInCall(const CallBase *callBase, const Value *arg);

public:
/// get or infer the class names of thisptr
Set<std::string> &inferThisPtrClsName(const Value *thisPtr);

protected:

/// find all possible allocations or
/// class name sources (e.g., constructors/destructors or template functions) starting from a value
Set<const Value *> &bwFindAllocOrClsNameSources(const Value *startValue);

/// forward find class name sources starting from an allocation
Set<const Function *> &fwFindClsNameSources(const CallBase *alloc);
};
}
#endif //SVF_OBJTYPEINFERENCE_H
25 changes: 18 additions & 7 deletions svf-llvm/lib/CHGBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -685,13 +685,24 @@ const CHGraph::CHNodeSetTy& CHGBuilder::getCSClasses(const CallBase* cs)
}
else
{
string thisPtrClassName = cppUtil::getClassNameOfThisPtr(cs);
if (const CHNode* thisNode = chg->getNode(thisPtrClassName))
{
const CHGraph::CHNodeSetTy& instAndDesces = getInstancesAndDescendants(thisPtrClassName);
chg->csToClassesMap[svfcall].insert(thisNode);
for (CHGraph::CHNodeSetTy::const_iterator it = instAndDesces.begin(), eit = instAndDesces.end(); it != eit; ++it)
chg->csToClassesMap[svfcall].insert(*it);
Set<string> thisPtrClassNames = getClassNameOfThisPtr(cs);

if(thisPtrClassNames.empty()) {
// if we cannot infer classname, conservatively push all class nodes
for (const auto &node: *chg) {
chg->csToClassesMap[svfcall].insert(node.second);
}
return chg->csToClassesMap[svfcall];
}

for (const auto &thisPtrClassName: thisPtrClassNames) {
if (const CHNode* thisNode = chg->getNode(thisPtrClassName))
{
const CHGraph::CHNodeSetTy& instAndDesces = getInstancesAndDescendants(thisPtrClassName);
chg->csToClassesMap[svfcall].insert(thisNode);
for (CHGraph::CHNodeSetTy::const_iterator it2 = instAndDesces.begin(), eit = instAndDesces.end(); it2 != eit; ++it2)
chg->csToClassesMap[svfcall].insert(*it2);
}
}
return chg->csToClassesMap[svfcall];
}
Expand Down
Loading

0 comments on commit 86dee72

Please sign in to comment.