38#include "llvm/Demangle/Demangle.h"
59const std::string
znwm =
"_Znwm";
81const std::string
dyncast =
"__dynamic_cast";
90 while (
leftpos != std::string::npos)
98 while (
rightpos != std::string::npos)
168 dname.isThunkFunc =
true;
206 auto trim = [](std::string&
s)
208 size_t first =
s.find_first_not_of(
' ');
209 size_t last =
s.find_last_not_of(
' ');
210 if (
first != std::string::npos &&
last != std::string::npos)
223 while (!
s.empty() && (
s.back() ==
'*' ||
s.back() ==
'&'))
235 if (start == std::string::npos || end == std::string::npos || start >= end)
246 while (std::getline(
ss, param,
','))
267 SVFUtil::isa<ConstantStruct>(
vtblStruct->getOperand(0)) &&
268 vtblStruct->getOperand(1)->getType()->isArrayTy())
269 return SVFUtil::cast<ConstantStruct>(
vtblStruct->getOperand(0));
276 if (!SVFUtil::isa<GlobalVariable>(
val))
293 if (cs->getCalledFunction() !=
nullptr || cs->arg_empty())
298 if (cs->getArgOperand(0)->getType()->isPointerTy() ==
false)
306 SVFUtil::dyn_cast<GetElementPtrInst>(
vfuncptr))
311 if (SVFUtil::isa<LoadInst>(
vtbl))
323 return dname.isThunkFunc;
332 for (
auto& inst : bb)
340 ret =
callbase->getCalledFunction();
350 if (cs->paramHasAttr(0, llvm::Attribute::StructRet))
352 return cs->getArgOperand(1);
356 return cs->getArgOperand(0);
364 V =
V->stripPointerCasts();
368 if (
const LoadInst* load = SVFUtil::dyn_cast<LoadInst>(
V))
371 SVFUtil::dyn_cast<AllocaInst>(load->getPointerOperand()))
375 if (
const StoreInst* store = SVFUtil::dyn_cast<StoreInst>(
U))
377 if (store->getPointerOperand() ==
alloca &&
378 store->getValueOperand()->stripPointerCasts() ==
thisPtr)
442 return GEP->getSourceElementType()->isIntegerTy(8);
450 for (
const Value*
storeU : store->getPointerOperand()->users())
454 if (load->getNextNode() &&
455 SVFUtil::isa<CastInst>(load->getNextNode()))
456 return SVFUtil::cast<CastInst>(load->getNextNode()) ==
468 "not a constructor?");
470 assert(fun->arg_size() >= 1 &&
"expected at least one argument");
473 const bool isStructRet = fun->hasParamAttribute(0, llvm::Attribute::StructRet);
489 if (
colon == std::string::npos)
503 if (F->isDeclaration())
505 std::string funcName = F->getName().str();
511 if (
dname.className.size() == 0)
517 return dname.className.size() > 0 &&
523 if (F->isDeclaration())
525 std::string
funcName = F->getName().str();
531 if (
dname.className.size() == 0)
536 return (
dname.className.size() > 0 &&
dname.funcName.size() > 0 &&
537 dname.className.size() + 1 ==
dname.funcName.size() &&
538 dname.funcName.compare(0, 1,
"~") == 0 &&
539 dname.className.compare(
dname.funcName.substr(1)) == 0);
552 SVFUtil::dyn_cast<LoadInst>(cs->getCalledOperand());
556 SVFUtil::dyn_cast<GetElementPtrInst>(
vfuncptr);
585 for(
auto it =
ty->element_begin(); it!=
ty->element_end(); it++)
598 if (!((SVFUtil::cast<StructType>(
ty))->
isLiteral()))
617 if (
const MDNode*
N = inst->getMetadata(
"VCallPtrType"))
619 const MDString*
mdstr = SVFUtil::cast<MDString>(
N->getOperand(0).get());
633 size_t found = thisPtrName.find_last_not_of(
"0123456789");
634 if (found != std::string::npos)
636 if (found != thisPtrName.size() - 1 &&
637 thisPtrName[found] ==
'.')
639 return thisPtrName.substr(0, found);
650 if (
const MDNode*
N = inst->getMetadata(
"VCallFunName"))
652 const MDString*
mdstr = SVFUtil::cast<MDString>(
N->getOperand(0).get());
661 SVFUtil::dyn_cast<LoadInst>(cs->getCalledOperand());
665 SVFUtil::dyn_cast<GetElementPtrInst>(
vfuncptr);
690 else if (!
v->hasInitializer())
692 return !
v->isExternalLinkage(
v->getLinkage());
698 for (std::vector<const SVFType*>::const_iterator it = fields.begin(),
eit = fields.end(); it !=
eit; ++it)
701 assert(!SVFUtil::isa<SVFFunctionType>(
elemTy) &&
"Initializer of a global is a function?");
702 if (SVFUtil::isa<SVFPointerType>(
elemTy))
706 return v->isConstant();
720 const std::string &
name =
foo->getName().str();
749 std::stack<int>
stack;
751 std::vector<bool>
used(
input.length(),
false);
787 return input.substr(p.first + 1, p.second - p.first - 1);
799 auto start = std::find_if(
str.begin(),
str.end(), [](
unsigned char ch)
801 return !std::isspace(ch);
803 auto end = std::find_if(
str.rbegin(),
str.rend(), [](
unsigned char ch)
805 return !std::isspace(ch);
808 return (start < end) ? std::string(start, end) : std::string();
813 std::vector<std::string>
tokens;
814 size_t start = 0, end = 0;
854 if (
starPos != std::string::npos)
874 if (
const auto *
callBase = SVFUtil::dyn_cast<CallBase>(
val))
878 if(!
foo)
return false;
881 else if (
const auto *
func = SVFUtil::dyn_cast<Function>(
val))
907 const std::string &
name =
foo->getName().str();
962 llvm::Triple
triple(
M->getTargetTriple());
963 if (
triple.isKnownWindowsMSVCEnvironment() ||
964 triple.isOSBinFormatCOFF())
984 return getCXXABI(I->getFunction()->getParent());
1024 if (
dname.className.size() == 0)
1029 return dname.className.size() > 0 &&
dname.className ==
dname.funcName;
1039 if (
dname.className.size() == 0)
1044 return (
dname.className.size() > 0 &&
dname.funcName.size() > 0 &&
1045 dname.className.size() + 1 ==
dname.funcName.size() &&
1046 dname.funcName.compare(0, 1,
"~") == 0 &&
1047 dname.className.compare(
dname.funcName.substr(1)) == 0);
1052 std::string className =
"";
1073 dname.className =
"";
1074 dname.funcName =
"";
1082 dname.className =
"";
1083 dname.funcName =
"";
1089 if (
colon == std::string::npos)
1091 dname.className =
"";
1092 dname.funcName =
"";
1109 return name.compare(0, 4,
"??_7") == 0 ||
name.compare(0, 4,
"??_8") == 0;
1114 return name.compare(0, 4,
"??_R") == 0;
1119 return name.compare(0, 3,
"??0") == 0;
1124 return name.compare(0, 3,
"??1") == 0;
1129 std::string className =
"";
1132 if (
pos == std::string::npos)
1136 if (
pos != std::string::npos)
1139 if (className.compare(0, 6,
"const ") == 0)
1141 className = className.substr(6);
1155 dname.className =
"";
1156 dname.funcName =
"";
1160 if (
realnameStr.find(
"[thunk]") != std::string::npos ||
1161 realnameStr.find(
"`vcall'") != std::string::npos ||
1162 realnameStr.find(
"`adjustor'") != std::string::npos)
1164 dname.isThunkFunc =
true;
1171 dname.className =
"";
1172 dname.funcName =
"";
1178 if (
colon == std::string::npos)
1180 dname.className =
"";
1181 dname.funcName =
"";
1208 if (std::isalnum(
c) ||
c ==
'_' ||
c ==
':' ||
c ==
'<' ||
const std::string znst6Label
const std::string znkst23Label
const std::string vtblLabelBeforeDemangle
static void handleThunkFunction(cppUtil::DemangledName &dname)
static bool isOperOverload(const std::string &name)
const std::string VThunkFuncLabel
static std::string getBeforeParenthesis(const std::string &name)
const std::string znkst20Label
const std::string znst5Label
const std::string vtblLabelAfterDemangle
static bool isDerivedFromThisPtr(const Argument *thisPtr, const Value *V)
const std::string clsName
const std::string structName
const std::string znstLabel
std::string stripWhitespaces(const std::string &str)
const std::string zn1Label
std::vector< std::string > findInnermostBrackets(const std::string &input)
const std::string znkstLabel
const std::string znst7Label
const std::string dyncast
const std::string znst12Label
const std::string NVThunkFunLabel
const std::string znkLabel
const std::string vtableType
const std::string ztilabel
std::vector< std::string > splitAndStrip(const std::string &input, char delimiter)
const std::string znst14Label
const std::string znk9Label
const std::string znkst5Label
void stripBracketsAndNamespace(cppUtil::DemangledName &dname)
const std::string ztiprefix
const std::string vfunPreLabel
static LLVMModuleSet * getLLVMModuleSet()
SVFType * getSVFType(const Type *T)
Get or create SVFType and typeinfo.
ObjTypeInference * getTypeInference()
Set< std::string > & inferThisPtrClsName(const Value *thisPtr)
get or infer the class names of thisptr
const Type * ptrType()
pointer type
std::vector< const SVFType * > & getFlattenFieldTypes()
virtual DemangledName demangle(const std::string &name)=0
virtual std::string extractClassName(const std::string &name)=0
virtual bool isVtable(const std::string &name)=0
std::string extractClassName(const std::string &name) override
bool isVtable(const std::string &name) override
bool isDestructor(const std::string &name) override
bool isConstructor(const std::string &name) override
DemangledName demangle(const std::string &name) override
bool isTypeInfo(const std::string &name) override
bool isTypeInfo(const std::string &name) override
DemangledName demangle(const std::string &name) override
bool isDestructor(const std::string &name) override
bool isVtable(const std::string &name) override
bool isConstructor(const std::string &name) override
std::string extractClassName(const std::string &name) override
bool isConstantObjSym(const Value *val)
Check whether this value points-to a constant object.
std::string dumpType(const Type *type)
std::pair< s64_t, u64_t > getIntegerValue(const ConstantInt *intValue)
bool isConstDataOrAggData(const Value *val)
Return true if the value refers to constant data, e.g., i32 0.
std::string dumpValue(const Value *val)
std::ostream & errs()
Overwrite llvm::errs()
std::string getFunNameOfVCallSite(const CallBase *cs)
std::string getBeforeBrackets(const std::string &name)
const Argument * getConstructorThisPtr(const Function *fun)
std::string extractClsNameFromDynCast(const CallBase *callBase)
extract class name from cpp dyncast function
s32_t getVCallIdx(const CallBase *cs)
const Value * getVCallVtblPtr(const CallBase *cs)
bool isTemplateFunc(const Function *foo)
whether foo is a cpp template function
bool classTyHasVTable(const StructType *ty)
bool isSameThisPtrInConstructor(const Argument *thisPtr1, const Value *thisPtr2)
Set< std::string > getClsNamesInBrackets(const std::string &name)
const Value * getVCallThisPtr(const CallBase *cs)
bool matchesLabel(const std::string &foo, const std::string &label)
whether foo matches the mangler label
std::string getClassNameFromType(const StructType *ty)
struct DemangledName demangle(const std::string &name)
Set< std::string > getClassNameOfThisPtr(const CallBase *cs)
bool isCPPThunkFunction(const Function *F)
bool VCallInCtorOrDtor(const CallBase *cs)
bool isClsNameSource(const Value *val)
Set< std::string > extractClsNamesFromTemplate(const std::string &oname)
extract class names from template functions
bool isVirtualCallSite(const CallBase *cs)
const Type * cppClsNameToType(const std::string &className)
const Function * getThunkTarget(const Function *F)
const ConstantStruct * getVtblStruct(const GlobalValue *vtbl)
bool isConstructor(const Function *F)
std::string getClassNameFromVtblObj(const std::string &vtblName)
Set< std::string > extractClsNamesFromFunc(const Function *foo)
extract class name from the c++ function name, e.g., constructor/destructors
bool isValVtbl(const Value *val)
A carefully crafted input such as FakeVTable _ZTV1A = {{nullptr, nullptr}}; can forge a vtable; detec...
bool isDestructor(const Function *F)
bool isDynCast(const Function *foo)
whether foo is a cpp dyncast function
llvm::GlobalVariable GlobalVariable
llvm::ConstantStruct ConstantStruct
llvm::StructType StructType
LLVM types.
llvm::AllocaInst AllocaInst
llvm::GlobalValue GlobalValue
llvm::Instruction Instruction
llvm::Value Value
LLVM Basic classes.
llvm::IRBuilder IRBuilder
llvm::StoreInst StoreInst
llvm::GetElementPtrInst GetElementPtrInst
llvm::ConstantInt ConstantInt